[PATCH v1 3/6] KVM: arm64: Move pkvm_mem_abort()

Fuad Tabba fuad.tabba at linux.dev
Wed Sep 23 12:38:38 PDT 2026


On Tue, 22 Sept 2026 at 14:08, 'Vincent Donnefort' via kernel-team
<kernel-team at android.com> wrote:
>
> Move pkvm_mem_abort() below kvm_s2_fault_get_vma_info() so it can
> resolve stage-2 fault VMA metadata without forward declarations.
>
> No functional change intended.
>
> Signed-off-by: Vincent Donnefort <vdonnefort at google.com>

Reviewed-by: Fuad Tabba <fuad.tabba at linux.dev>
Tested-by: Fuad Tabba < fuad.tabba at linux.dev>

Cheers,
/fuad


> ---
>  arch/arm64/kvm/mmu.c | 138 +++++++++++++++++++++----------------------
>  1 file changed, 69 insertions(+), 69 deletions(-)
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 9dfaf4f277b5..242f63066252 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1706,75 +1706,6 @@ struct kvm_s2_fault_vma_info {
>         bool            map_non_cacheable;
>  };
>
> -static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> -{
> -       unsigned int flags = FOLL_HWPOISON | FOLL_LONGTERM | FOLL_WRITE;
> -       struct kvm_vcpu *vcpu = s2fd->vcpu;
> -       struct kvm_pgtable *pgt = vcpu->arch.hw_mmu->pgt;
> -       struct mm_struct *mm = current->mm;
> -       struct kvm *kvm = vcpu->kvm;
> -       void *hyp_memcache;
> -       struct page *page;
> -       int ret;
> -
> -       hyp_memcache = get_mmu_memcache(vcpu);
> -       ret = topup_mmu_memcache(vcpu, hyp_memcache);
> -       if (ret)
> -               return -ENOMEM;
> -
> -       ret = account_locked_vm(mm, 1, true);
> -       if (ret)
> -               return ret;
> -
> -       mmap_read_lock(mm);
> -       ret = pin_user_pages(s2fd->hva, 1, flags, &page);
> -       mmap_read_unlock(mm);
> -
> -       if (ret == -EHWPOISON) {
> -               kvm_send_hwpoison_signal(s2fd->hva, PAGE_SHIFT);
> -               ret = 0;
> -               goto dec_account;
> -       } else if (ret != 1) {
> -               ret = -EFAULT;
> -               goto dec_account;
> -       } else if (!folio_test_swapbacked(page_folio(page))) {
> -               /*
> -                * We really can't deal with page-cache pages returned by GUP
> -                * because (a) we may trigger writeback of a page for which we
> -                * no longer have access and (b) page_mkclean() won't find the
> -                * stage-2 mapping in the rmap so we can get out-of-whack with
> -                * the filesystem when marking the page dirty during unpinning
> -                * (see cc5095747edf ("ext4: don't BUG if someone dirty pages
> -                * without asking ext4 first")).
> -                *
> -                * Ideally we'd just restrict ourselves to anonymous pages, but
> -                * we also want to allow memfd (i.e. shmem) pages, so check for
> -                * pages backed by swap in the knowledge that the GUP pin will
> -                * prevent try_to_unmap() from succeeding.
> -                */
> -               ret = -EIO;
> -               goto unpin;
> -       }
> -
> -       write_lock(&kvm->mmu_lock);
> -       ret = pkvm_pgtable_stage2_map(pgt, s2fd->fault_ipa, PAGE_SIZE,
> -                                     page_to_phys(page), KVM_PGTABLE_PROT_RWX,
> -                                     hyp_memcache, 0);
> -       write_unlock(&kvm->mmu_lock);
> -       if (ret) {
> -               if (ret == -EAGAIN)
> -                       ret = 0;
> -               goto unpin;
> -       }
> -
> -       return 0;
> -unpin:
> -       unpin_user_pages(&page, 1);
> -dec_account:
> -       account_locked_vm(mm, 1, false);
> -       return ret;
> -}
> -
>  static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd,
>                                      struct kvm_s2_fault_vma_info *s2vi,
>                                      struct vm_area_struct *vma)
> @@ -2235,6 +2166,75 @@ int kvm_handle_guest_sea(struct kvm_vcpu *vcpu)
>         return 0;
>  }
>
> +static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> +{
> +       unsigned int flags = FOLL_HWPOISON | FOLL_LONGTERM | FOLL_WRITE;
> +       struct kvm_vcpu *vcpu = s2fd->vcpu;
> +       struct kvm_pgtable *pgt = vcpu->arch.hw_mmu->pgt;
> +       struct mm_struct *mm = current->mm;
> +       struct kvm *kvm = vcpu->kvm;
> +       void *hyp_memcache;
> +       struct page *page;
> +       int ret;
> +
> +       hyp_memcache = get_mmu_memcache(vcpu);
> +       ret = topup_mmu_memcache(vcpu, hyp_memcache);
> +       if (ret)
> +               return -ENOMEM;
> +
> +       ret = account_locked_vm(mm, 1, true);
> +       if (ret)
> +               return ret;
> +
> +       mmap_read_lock(mm);
> +       ret = pin_user_pages(s2fd->hva, 1, flags, &page);
> +       mmap_read_unlock(mm);
> +
> +       if (ret == -EHWPOISON) {
> +               kvm_send_hwpoison_signal(s2fd->hva, PAGE_SHIFT);
> +               ret = 0;
> +               goto dec_account;
> +       } else if (ret != 1) {
> +               ret = -EFAULT;
> +               goto dec_account;
> +       } else if (!folio_test_swapbacked(page_folio(page))) {
> +               /*
> +                * We really can't deal with page-cache pages returned by GUP
> +                * because (a) we may trigger writeback of a page for which we
> +                * no longer have access and (b) page_mkclean() won't find the
> +                * stage-2 mapping in the rmap so we can get out-of-whack with
> +                * the filesystem when marking the page dirty during unpinning
> +                * (see cc5095747edf ("ext4: don't BUG if someone dirty pages
> +                * without asking ext4 first")).
> +                *
> +                * Ideally we'd just restrict ourselves to anonymous pages, but
> +                * we also want to allow memfd (i.e. shmem) pages, so check for
> +                * pages backed by swap in the knowledge that the GUP pin will
> +                * prevent try_to_unmap() from succeeding.
> +                */
> +               ret = -EIO;
> +               goto unpin;
> +       }
> +
> +       write_lock(&kvm->mmu_lock);
> +       ret = pkvm_pgtable_stage2_map(pgt, s2fd->fault_ipa, PAGE_SIZE,
> +                                     page_to_phys(page), KVM_PGTABLE_PROT_RWX,
> +                                     hyp_memcache, 0);
> +       write_unlock(&kvm->mmu_lock);
> +       if (ret) {
> +               if (ret == -EAGAIN)
> +                       ret = 0;
> +               goto unpin;
> +       }
> +
> +       return 0;
> +unpin:
> +       unpin_user_pages(&page, 1);
> +dec_account:
> +       account_locked_vm(mm, 1, false);
> +       return ret;
> +}
> +
>  /**
>   * kvm_handle_guest_abort - handles all 2nd stage aborts
>   * @vcpu:      the VCPU pointer
> --
> 2.55.0.1082.g2b9226bbc0-goog
>
> To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe at android.com.
>



More information about the linux-arm-kernel mailing list