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:
Quentin Perret
2025-01-20 16:12:57 +00:00
parent 40f82019f6
commit 1d36cbcba4
+4 -10
View File
@@ -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;