Skip to content

Commit d4ad442

Browse files
Marc Zyngiergregkh
authored andcommitted
arm/arm64: KVM: Take mmap_sem in kvm_arch_prepare_memory_region
commit 72f310481a08db821b614e7b5d00febcc9064b36 upstream. We don't hold the mmap_sem while searching for VMAs (via find_vma), in kvm_arch_prepare_memory_region, which can end up in expected failures. Fixes: commit 8eef912 ("arm/arm64: KVM: map MMIO regions at creation time") Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Eric Auger <eric.auger@rehat.com> Reviewed-by: Christoffer Dall <cdall@linaro.org> [ Handle dirty page logging failure case ] Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8e88806 commit d4ad442

1 file changed

Lines changed: 8 additions & 3 deletions

File tree

arch/arm/kvm/mmu.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1761,6 +1761,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
17611761
(KVM_PHYS_SIZE >> PAGE_SHIFT))
17621762
return -EFAULT;
17631763

1764+
down_read(&current->mm->mmap_sem);
17641765
/*
17651766
* A memory region could potentially cover multiple VMAs, and any holes
17661767
* between them, so iterate over all of them to find out if we can map
@@ -1804,8 +1805,10 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
18041805
pa += vm_start - vma->vm_start;
18051806

18061807
/* IO region dirty page logging not allowed */
1807-
if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES)
1808-
return -EINVAL;
1808+
if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) {
1809+
ret = -EINVAL;
1810+
goto out;
1811+
}
18091812

18101813
ret = kvm_phys_addr_ioremap(kvm, gpa, pa,
18111814
vm_end - vm_start,
@@ -1817,14 +1820,16 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
18171820
} while (hva < reg_end);
18181821

18191822
if (change == KVM_MR_FLAGS_ONLY)
1820-
return ret;
1823+
goto out;
18211824

18221825
spin_lock(&kvm->mmu_lock);
18231826
if (ret)
18241827
unmap_stage2_range(kvm, mem->guest_phys_addr, mem->memory_size);
18251828
else
18261829
stage2_flush_memslot(kvm, memslot);
18271830
spin_unlock(&kvm->mmu_lock);
1831+
out:
1832+
up_read(&current->mm->mmap_sem);
18281833
return ret;
18291834
}
18301835

0 commit comments

Comments
 (0)