ANDROID: BACKPORT: KVM: arm64: Handle races gracefully in pkvm_relax_perms()
We may encounter a race between MMU notifiers and the perm fault path in KVM where the faulting PFN is gone from the maple tree by the time we check it in pkvm_relax_perms(). Although that race is benign, it currently causes the vCPU to exit with -EFAULT, which is generally fatal for the guest. To avoid this problem, let's return -EAGAIN instead and give the guest another chance. BACKPORT: adapted from android15-6.6 code which had a variation of the same bug. Bug: 389901612 Change-Id: Ie98e1162a558126c8c6e83f0621460966c09b7ad Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
+4
-10
@@ -1654,18 +1654,12 @@ static int pkvm_relax_perms(struct kvm *kvm, u64 pfn, u64 gfn,
|
||||
struct kvm_pinned_page *ppage;
|
||||
int ret;
|
||||
|
||||
WARN_ON(kvm_vm_is_protected(kvm));
|
||||
|
||||
ppage = find_ppage(kvm, gfn << PAGE_SHIFT);
|
||||
|
||||
/*
|
||||
* In the rare case that we raced with an MMU notifier, the page might
|
||||
* already be gone by now, so let's just try again.
|
||||
*/
|
||||
if (!ppage)
|
||||
return kvm->arch.pkvm.enabled ? -EAGAIN : -EFAULT;
|
||||
|
||||
if (page_to_pfn(ppage->page) != pfn)
|
||||
return -EFAULT;
|
||||
/* Try again if we raced with an MMU notifier. */
|
||||
if (!ppage || page_to_pfn(ppage->page) != pfn)
|
||||
return -EAGAIN;
|
||||
|
||||
if (!folio_test_swapbacked(page_folio(ppage->page)))
|
||||
return -EIO;
|
||||
|
||||
Reference in New Issue
Block a user