[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