* [PATCH v2] KVM: arm64: Fix protected VM fault on system with pages larger than 4K
@ 2026-09-14 7:58 Vincent Donnefort
2026-09-14 8:13 ` sashiko-bot
2026-09-14 8:32 ` Marc Zyngier
0 siblings, 2 replies; 6+ messages in thread
From: Vincent Donnefort @ 2026-09-14 7:58 UTC (permalink / raw)
To: maz, oupton, kvmarm, linux-arm-kernel
Cc: joey.gouly, seiden, suzuki.poulose, yuzenghui, catalin.marinas,
will, kernel-team, fuad.tabba, qperret, Vincent Donnefort
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 use the gfn as an argument in all
callers.
Fixes: ea03466e806f ("KVM: arm64: Handle aborts from protected VMs")
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
---
Changelog:
v2:
- 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/
arch/arm64/kvm/mmu.c | 7 ++++---
arch/arm64/kvm/pkvm.c | 3 +++
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 9ba86450fe4a..ee78201a44df 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1672,10 +1672,10 @@ 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, gfn_to_gpa(gfn),
prot, flags);
} else {
- ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
+ ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, gfn_to_gpa(gfn), PAGE_SIZE,
__pfn_to_phys(pfn), prot,
memcache, flags);
}
@@ -1710,6 +1710,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 +1757,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;
+
lockdep_assert_held_write(&kvm->mmu_lock);
mapping = pkvm_mapping_iter_first(&pgt->pkvm_mappings, addr, end - 1);
base-commit: df2908090cda368b01ff43709f51890076c56157
--
2.55.0.1007.g17ff1f9808-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH v2] KVM: arm64: Fix protected VM fault on system with pages larger than 4K
2026-09-14 7:58 [PATCH v2] KVM: arm64: Fix protected VM fault on system with pages larger than 4K Vincent Donnefort
@ 2026-09-14 8:13 ` sashiko-bot
2026-09-14 8:19 ` Vincent Donnefort
2026-09-14 8:32 ` Marc Zyngier
1 sibling, 1 reply; 6+ messages in thread
From: sashiko-bot @ 2026-09-14 8:13 UTC (permalink / raw)
To: Vincent Donnefort; +Cc: kvmarm, Oliver Upton, Marc Zyngier
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The patch incorrectly maps the guest PA (L1 IPA) instead of the guest IPA (L2 IPA) in the shadow stage-2 page tables for nested VMs in `gmem_abort()`.
--
commit 3995ce8aa44bf10fe23cdc5e9257510868df129d
Author: Vincent Donnefort <vdonnefort@google.com>
KVM: arm64: Fix protected VM fault on system with pages larger than 4K
This commit aligns the fault IPA down to the page-size for protected VMs to
fix boot issues on systems with larger than 4K pages. It updates
pkvm_pgtable_stage2_map() to require page-aligned arguments and changes the
callers to pass gfn_to_gpa(gfn) instead of the raw fault_ipa.
Link: 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 9ba86450fe4af..ee78201a44df1 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1672,10 +1672,10 @@ 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, gfn_to_gpa(gfn),
> prot, flags);
> } else {
> - ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
> + ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, gfn_to_gpa(gfn), PAGE_SIZE,
> __pfn_to_phys(pfn), prot,
> memcache, flags);
> }
[Severity: High]
Does this change break nested virtualization by mapping the guest PA (L1 IPA)
instead of the faulting guest IPA (L2 IPA)?
For nested VMs handled in gmem_abort(), gfn represents the L1 IPA. By
switching from s2fd->fault_ipa to gfn_to_gpa(gfn) in both
kvm_pgtable_stage2_relax_perms() and kvm_pgtable_stage2_map(), the shadow
stage-2 page tables now incorrectly install the mapping at the L1 IPA instead
of the expected L2 IPA.
This results in the L2 guest continuously faulting at the same L2 IPA, leading
to an infinite fault loop (DoS for the nested guest) and shadow page table
corruption.
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260914075839.4019904-1-vdonnefort@google.com?part=1
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH v2] KVM: arm64: Fix protected VM fault on system with pages larger than 4K
2026-09-14 8:13 ` sashiko-bot
@ 2026-09-14 8:19 ` Vincent Donnefort
0 siblings, 0 replies; 6+ messages in thread
From: Vincent Donnefort @ 2026-09-14 8:19 UTC (permalink / raw)
To: sashiko-reviews; +Cc: kvmarm, Oliver Upton, Marc Zyngier
On Mon, Sep 14, 2026 at 08:13:42AM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [High] The patch incorrectly maps the guest PA (L1 IPA) instead of the guest IPA (L2 IPA) in the shadow stage-2 page tables for nested VMs in `gmem_abort()`.
> --
>
> commit 3995ce8aa44bf10fe23cdc5e9257510868df129d
> Author: Vincent Donnefort <vdonnefort@google.com>
>
> KVM: arm64: Fix protected VM fault on system with pages larger than 4K
>
> This commit aligns the fault IPA down to the page-size for protected VMs to
> fix boot issues on systems with larger than 4K pages. It updates
> pkvm_pgtable_stage2_map() to require page-aligned arguments and changes the
> callers to pass gfn_to_gpa(gfn) instead of the raw fault_ipa.
>
> Link: 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 9ba86450fe4af..ee78201a44df1 100644
> > --- a/arch/arm64/kvm/mmu.c
> > +++ b/arch/arm64/kvm/mmu.c
> > @@ -1672,10 +1672,10 @@ 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, gfn_to_gpa(gfn),
> > prot, flags);
> > } else {
> > - ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
> > + ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, gfn_to_gpa(gfn), PAGE_SIZE,
> > __pfn_to_phys(pfn), prot,
> > memcache, flags);
> > }
>
> [Severity: High]
> Does this change break nested virtualization by mapping the guest PA (L1 IPA)
> instead of the faulting guest IPA (L2 IPA)?
>
> For nested VMs handled in gmem_abort(), gfn represents the L1 IPA. By
> switching from s2fd->fault_ipa to gfn_to_gpa(gfn) in both
> kvm_pgtable_stage2_relax_perms() and kvm_pgtable_stage2_map(), the shadow
> stage-2 page tables now incorrectly install the mapping at the L1 IPA instead
> of the expected L2 IPA.
>
> This results in the L2 guest continuously faulting at the same L2 IPA, leading
> to an infinite fault loop (DoS for the nested guest) and shadow page table
> corruption.
>
> [ ... ]
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260914075839.4019904-1-vdonnefort@google.com?part=1
That's indeed not possible to use gfn in gmem_abort()
So I guess ALIGN_DOWN(s2fd->fault_ipa, PAGE_SIZE) will do.
--
Vincent
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] KVM: arm64: Fix protected VM fault on system with pages larger than 4K
2026-09-14 7:58 [PATCH v2] KVM: arm64: Fix protected VM fault on system with pages larger than 4K Vincent Donnefort
2026-09-14 8:13 ` sashiko-bot
@ 2026-09-14 8:32 ` Marc Zyngier
2026-09-14 8:40 ` Fuad Tabba
2026-09-14 8:41 ` Vincent Donnefort
1 sibling, 2 replies; 6+ messages in thread
From: Marc Zyngier @ 2026-09-14 8:32 UTC (permalink / raw)
To: Vincent Donnefort
Cc: oupton, kvmarm, linux-arm-kernel, joey.gouly, seiden,
suzuki.poulose, yuzenghui, catalin.marinas, will, kernel-team,
fuad.tabba, qperret
On Mon, 14 Sep 2026 08:58:39 +0100,
Vincent Donnefort <vdonnefort@google.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 use the gfn as an argument in all
> callers.
>
> Fixes: ea03466e806f ("KVM: arm64: Handle aborts from protected VMs")
> Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
> ---
>
> Changelog:
>
> v2:
> - 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/
>
> arch/arm64/kvm/mmu.c | 7 ++++---
> arch/arm64/kvm/pkvm.c | 3 +++
> 2 files changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 9ba86450fe4a..ee78201a44df 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1672,10 +1672,10 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
> * PTE, which will be preserved.
> */
Context:
if (s2fd->nested)
gfn = kvm_s2_trans_output(s2fd->nested) >> PAGE_SHIFT;
else
gfn = s2fd->fault_ipa >> PAGE_SHIFT;
[...]
> 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, gfn_to_gpa(gfn),
> prot, flags);
> } else {
> - ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
> + ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, gfn_to_gpa(gfn), PAGE_SIZE,
> __pfn_to_phys(pfn), prot,
> memcache, flags);
So 'gfn' is not related to the faulting IPA in the nested case, but is
the output address of the guest's own S2. You probably end-up with a
livelock handling the same fault forever, or worse.
It is a bit annoying that neither gmem nor pkvm are using
kvm_s2_fault_vma_info, which has the ability to reports all the
important stuff, as it would avoid this sort of bugs.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH v2] KVM: arm64: Fix protected VM fault on system with pages larger than 4K
2026-09-14 8:32 ` Marc Zyngier
@ 2026-09-14 8:40 ` Fuad Tabba
2026-09-14 8:41 ` Vincent Donnefort
1 sibling, 0 replies; 6+ messages in thread
From: Fuad Tabba @ 2026-09-14 8:40 UTC (permalink / raw)
To: Marc Zyngier
Cc: Vincent Donnefort, oupton, kvmarm, linux-arm-kernel, joey.gouly,
seiden, suzuki.poulose, yuzenghui, catalin.marinas, will,
kernel-team, qperret
On Mon, 14 Sept 2026 at 09:32, Marc Zyngier <maz@kernel.org> wrote:
...
> It is a bit annoying that neither gmem nor pkvm are using
> kvm_s2_fault_vma_info, which has the ability to reports all the
> important stuff, as it would avoid this sort of bugs.
That's on my list of things to tidy up, fwiw.
/fuad
>
> Thanks,
>
> M.
>
> --
> Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] KVM: arm64: Fix protected VM fault on system with pages larger than 4K
2026-09-14 8:32 ` Marc Zyngier
2026-09-14 8:40 ` Fuad Tabba
@ 2026-09-14 8:41 ` Vincent Donnefort
1 sibling, 0 replies; 6+ messages in thread
From: Vincent Donnefort @ 2026-09-14 8:41 UTC (permalink / raw)
To: Marc Zyngier
Cc: oupton, kvmarm, linux-arm-kernel, joey.gouly, seiden,
suzuki.poulose, yuzenghui, catalin.marinas, will, kernel-team,
fuad.tabba, qperret
On Mon, Sep 14, 2026 at 09:32:47AM +0100, Marc Zyngier wrote:
> On Mon, 14 Sep 2026 08:58:39 +0100,
> Vincent Donnefort <vdonnefort@google.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 use the gfn as an argument in all
> > callers.
> >
> > Fixes: ea03466e806f ("KVM: arm64: Handle aborts from protected VMs")
> > Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
> > ---
> >
> > Changelog:
> >
> > v2:
> > - 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/
> >
> > arch/arm64/kvm/mmu.c | 7 ++++---
> > arch/arm64/kvm/pkvm.c | 3 +++
> > 2 files changed, 7 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> > index 9ba86450fe4a..ee78201a44df 100644
> > --- a/arch/arm64/kvm/mmu.c
> > +++ b/arch/arm64/kvm/mmu.c
> > @@ -1672,10 +1672,10 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
> > * PTE, which will be preserved.
> > */
>
> Context:
>
> if (s2fd->nested)
> gfn = kvm_s2_trans_output(s2fd->nested) >> PAGE_SHIFT;
> else
> gfn = s2fd->fault_ipa >> PAGE_SHIFT;
>
> [...]
>
> > 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, gfn_to_gpa(gfn),
> > prot, flags);
> > } else {
> > - ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
> > + ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, gfn_to_gpa(gfn), PAGE_SIZE,
> > __pfn_to_phys(pfn), prot,
> > memcache, flags);
>
> So 'gfn' is not related to the faulting IPA in the nested case, but is
> the output address of the guest's own S2. You probably end-up with a
> livelock handling the same fault forever, or worse.
>
> It is a bit annoying that neither gmem nor pkvm are using
> kvm_s2_fault_vma_info, which has the ability to reports all the
> important stuff, as it would avoid this sort of bugs.
>
> Thanks,
>
> M.
>
> --
> Without deviation from the norm, progress is not possible.
Using kvm_s2_fault_vma_info would surely help the THP support for protected VMs
[1]. I am thinking now about bringing it as part of that series.
However for a fix, that's a bit much?
[1] https://lore.kernel.org/all/20260911135053.146435-23-vdonnefort@google.com/
--
Vincent
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-14 8:41 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-14 7:58 [PATCH v2] KVM: arm64: Fix protected VM fault on system with pages larger than 4K Vincent Donnefort
2026-09-14 8:13 ` sashiko-bot
2026-09-14 8:19 ` Vincent Donnefort
2026-09-14 8:32 ` Marc Zyngier
2026-09-14 8:40 ` Fuad Tabba
2026-09-14 8:41 ` Vincent Donnefort
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.