From: Vincent Donnefort <vdonnefort@google.com>
To: Fuad Tabba <fuad.tabba@linux.dev>
Cc: maz@kernel.org, oupton@kernel.org, kvmarm@lists.linux.dev,
linux-arm-kernel@lists.infradead.org, joey.gouly@arm.com,
seiden@linux.ibm.com, suzuki.poulose@arm.com,
yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org,
kernel-team@android.com, qperret@google.com
Subject: Re: [PATCH v3] KVM: arm64: Fix protected VM fault on system with pages larger than 4K
Date: Thu, 17 Sep 2026 09:25:11 +0100 [thread overview]
Message-ID: <aquj55DPnqs-AUwM@google.com> (raw)
In-Reply-To: <CA+EHjTz_c5BS3XgFuv61AtwgxD7WWELwuWZ3crd7_7RMvGA2Gw@mail.gmail.com>
On Tue, Sep 15, 2026 at 12:17:21PM +0100, Fuad Tabba wrote:
> Hi Vincent,
>
> On Tue, 15 Sept 2026 at 10:16, 'Vincent Donnefort' via kernel-team
> <kernel-team@android.com> wrote:
> >
> > Just like commit 08f97454b7fa ("KVM: arm64: Fix protected mode handling
> > of pages larger than 4kB") fixed the boot of non-protected VMs on system
> > larger than 4K pages, align the fault IPA down to the page-size for
> > protected VMs.
> >
> > To paraphrase Marc, pkvm_pgtable_stage2_map() assumes the address passed
> > as a parameter is aligned to the size of the intended mapping, while
> > HPFAR_EL2 gives the IPA minus the bottom 12 bits, regardless of the
> > system page size configuration.
> >
> > Add a check at the start of pkvm_pgtable_stage2_map() as we do not
> > support !PAGE_ALIGNED arguments and ensure callers pass a page-aligned
> > IPA.
>
> The fix is correct, and I can reproduce the bug. On a 16K-page host an
> unpatched v7.3-rc2 never gets a pVM to a prompt: no guest console
> output at all, a core pegged at 100% when I sampled it a minute in,
> killed at the 120s timeout. A guest_memfd-backed non-protected VM
> times out the same way, while one without guest_memfd boots fine,
> which puts the failure on the two paths you fix. With the patch all
> three boot clean, and 4K still boots both. That is QEMU with kvmtool
> guests; the same three 16K legs also pass on an M4 running pKVM at EL2
> on the silicon.
>
> Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
>
> > Fixes: ea03466e806f ("KVM: arm64: Handle aborts from protected VMs")
>
> A second Fixes: for the gmem_abort() half? a7b57e099592 ("KVM: arm64:
> Handle guest_memfd-backed guest page faults") added that call site,
> and the ranges differ: ea03466e806f is in v7.1, a7b57e099592 in v6.18.
>
> Should this carry Cc: stable@vger.kernel.org? 08f97454b7fa, the fix
> this one follows, did, and 16K-page hosts are a shipping Android
> configuration.
>
> > Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
> > ---
> > arch/arm64/kvm/mmu.c | 12 +++++++-----
> > arch/arm64/kvm/pkvm.c | 3 +++
> > 2 files changed, 10 insertions(+), 5 deletions(-)
> >
> > Changelog:
> >
> > v3:
> > - Fix nested case in gmem_abort() (Sashiko)
> >
> > v2: https://lore.kernel.org/all/20260914075839.4019904-1-vdonnefort@google.com/
> >
> > - Use gfn_to_gpa(gfn)
> > - Drop "phys" from the PAGE_ALIGNED check, it isn't a requirement.
> > - Fix gmem_abort() as well (Sashiko)
> >
> > v1: https://lore.kernel.org/all/20260913173516.3122436-1-vdonnefort@google.com/
> >
> > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> > index 9ba86450fe4a..e199dd339583 100644
> > --- a/arch/arm64/kvm/mmu.c
> > +++ b/arch/arm64/kvm/mmu.c
> > @@ -1610,6 +1610,7 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
> > bool write_fault, exec_fault;
> > bool perm_fault = kvm_vcpu_trap_is_permission_fault(s2fd->vcpu);
> > enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_SHARED;
> > + phys_addr_t ipa = ALIGN_DOWN(s2fd->fault_ipa, PAGE_SIZE);
> > enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
> > struct kvm_pgtable *pgt = s2fd->vcpu->arch.hw_mmu->pgt;
> > unsigned long mmu_seq;
>
> One more in gmem_abort(): the memory fault exit at mmu.c:1647 still
> reports the unaligned address, and that one is userspace-visible.
>
> kvm_prepare_memory_fault_exit(s2fd->vcpu, s2fd->fault_ipa, PAGE_SIZE,
> write_fault, exec_fault, false);
>
> api.rst defines the range as [gpa, gpa + size), so on a 16K host it
> starts mid-page. gfn_to_gpa(gfn) is the one to use: gfn is what
> kvm_gmem_get_pfn() failed on, and the L1 IPA in the nested case. x86
> passes fault->gfn << PAGE_SHIFT.
>
> > @@ -1672,12 +1673,12 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
> > * PTE, which will be preserved.
> > */
> > prot &= ~KVM_NV_GUEST_MAP_SZ;
> > - ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, s2fd->fault_ipa,
> > + ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, ipa,
> > prot, flags);
> > } else {
> > - ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
> > - __pfn_to_phys(pfn), prot,
> > - memcache, flags);
> > + ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, ipa, PAGE_SIZE,
> > + __pfn_to_phys(pfn),
> > + prot, memcache, flags);
> > }
> >
> > out_unlock:
> > @@ -1710,6 +1711,7 @@ 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;
> > + gfn_t gfn = gpa_to_gfn(s2fd->fault_ipa);
> > struct mm_struct *mm = current->mm;
> > struct kvm *kvm = vcpu->kvm;
> > void *hyp_memcache;
> > @@ -1756,7 +1758,7 @@ static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> > }
> >
> > write_lock(&kvm->mmu_lock);
> > - ret = pkvm_pgtable_stage2_map(pgt, s2fd->fault_ipa, PAGE_SIZE,
> > + ret = pkvm_pgtable_stage2_map(pgt, gfn_to_gpa(gfn), PAGE_SIZE,
> > page_to_phys(page), KVM_PGTABLE_PROT_RWX,
> > hyp_memcache, 0);
> > write_unlock(&kvm->mmu_lock);
> > diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
> > index 8e4c6e4bec12..b7340c430ed6 100644
> > --- a/arch/arm64/kvm/pkvm.c
> > +++ b/arch/arm64/kvm/pkvm.c
> > @@ -414,6 +414,9 @@ int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
> > u64 end = addr + size;
> > int ret;
> >
> > + if (!PAGE_ALIGNED(addr | size))
> > + return -EINVAL;
> > +
>
> Could this be if (WARN_ON_ONCE(!PAGE_ALIGNED(addr | size)))? The three
> checks just below WARN on the same class of caller bug, and this one
> runs first, so a bad size now returns -EINVAL with no splat.
>
> With the memory fault exit fixed:
> Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
>
> Cheers,
> /fuad
Thanks Fuad,
I'll modify that. Although in the new respin I will also add support for
kvm_s2_fault_vma_info(), which should naturally fix that issue, just like Marc
suggested [1]
[1] https://lore.kernel.org/all/864ifs6xn4.wl-maz@kernel.org/
--
Vincent
>
> > lockdep_assert_held_write(&kvm->mmu_lock);
> > mapping = pkvm_mapping_iter_first(&pgt->pkvm_mappings, addr, end - 1);
> >
> >
> > base-commit: df2908090cda368b01ff43709f51890076c56157
> > --
> > 2.55.0.1032.g73a4cd73de-goog
> >
> > To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe@android.com.
> >
>
> To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe@android.com.
>
next prev parent reply other threads:[~2026-09-17 8:25 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-15 9:16 [PATCH v3] KVM: arm64: Fix protected VM fault on system with pages larger than 4K Vincent Donnefort
2026-09-15 11:17 ` Fuad Tabba
2026-09-17 8:25 ` Vincent Donnefort [this message]
2026-09-17 8:49 ` Suzuki K Poulose
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aquj55DPnqs-AUwM@google.com \
--to=vdonnefort@google.com \
--cc=catalin.marinas@arm.com \
--cc=fuad.tabba@linux.dev \
--cc=joey.gouly@arm.com \
--cc=kernel-team@android.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=qperret@google.com \
--cc=seiden@linux.ibm.com \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.