* [PATCH v2 0/2] arm64: ptdump flush fixes
@ 2026-07-24 18:54 Wei-Lin Chang
2026-07-24 18:54 ` [PATCH v2 1/2] arm64: ptdump: Make note_page_flush() range aware Wei-Lin Chang
2026-07-24 18:54 ` [PATCH v2 2/2] KVM: arm64: ptdump: Flush the last region Wei-Lin Chang
0 siblings, 2 replies; 5+ messages in thread
From: Wei-Lin Chang @ 2026-07-24 18:54 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm, linux-kernel
Cc: Marc Zyngier, Oliver Upton, Fuad Tabba, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon,
Anshuman Khandual, Ryan Roberts, Dev Jain,
David Hildenbrand (Arm), Matt Fleming, Ard Biesheuvel,
Mark Rutland, Sebastian Ene, Vincent Donnefort, Wei-Lin Chang
Hi,
This series fixes two problems around ptdumps:
1. note_page_flush(), which flushes out the last row of ptdumps, does
not account for address spacees that have IA < 64. Other than making
the last region extremely huge, the attributes of the last region
within the address spaces appear to extend all the way to 1 << 64.
2. KVM/arm64's stage-2 ptdump missed calling note_page_flush().
Please see the patches for more detail.
* Changes from v1 [1]:
- Instead of manually calling note_page() for flushing, fix
note_page_flush() so that it ends the ptdump at the end of the
address space.
- Changed the start address of the second marker to ULONG_MAX for KVM
ptdump, so we don't output extra marker names, and advance past the
end of the marker array.
Thanks!
[1]: https://lore.kernel.org/kvmarm/20260717231233.2299068-1-weilin.chang@arm.com/
Wei-Lin Chang (2):
arm64: ptdump: Make note_page_flush() range aware
KVM: arm64: ptdump: Flush the last region
arch/arm64/kvm/ptdump.c | 16 ++++++++++++----
arch/arm64/mm/ptdump.c | 17 ++++++++++++++++-
2 files changed, 28 insertions(+), 5 deletions(-)
base-commit: 679d7201c1f09e37fa1c12ce28d84079c17fc87f
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v2 1/2] arm64: ptdump: Make note_page_flush() range aware 2026-07-24 18:54 [PATCH v2 0/2] arm64: ptdump flush fixes Wei-Lin Chang @ 2026-07-24 18:54 ` Wei-Lin Chang 2026-07-24 18:54 ` [PATCH v2 2/2] KVM: arm64: ptdump: Flush the last region Wei-Lin Chang 1 sibling, 0 replies; 5+ messages in thread From: Wei-Lin Chang @ 2026-07-24 18:54 UTC (permalink / raw) To: linux-arm-kernel, kvmarm, linux-kernel Cc: Marc Zyngier, Oliver Upton, Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon, Anshuman Khandual, Ryan Roberts, Dev Jain, David Hildenbrand (Arm), Matt Fleming, Ard Biesheuvel, Mark Rutland, Sebastian Ene, Vincent Donnefort, Wei-Lin Chang note_page_flush() calls note_page() with addr == 0 and level == -1 to dump the last row of a ptdump. addr == 0 (1 << 64 wrapped around) renders a huge region with enormous size for address spaces with IA bits < 64. For example the stage-2 page tables and the EFI runtime page table. More importantly, the last region of the address space and everything after the address space up to 1 << 64 are merged into one row of output. If the last region within the address space is valid, it will appear to remain valid up to 1 << 64 with the same attributes. Currently only the EFI runtime ptdump is affected by this, but KVM will soon fix its stage-2 ptdump by using note_page_flush(). Here is an example of an EFI runtime ptdump (last row): 0x0000008000000000-0x0000000000000000 17179868672G PGD With this patch: 0x0000008000000000-0x0001000000000000 261632G PGD To fix this, use ptdump_state.range[] to figure out where the address space ends, and call note_page() with that. Fixes: 9d80448ac92b ("efi/arm64: Add debugfs node to dump UEFI runtime page tables") Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com> --- arch/arm64/mm/ptdump.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c index 1c20144700d7..5b34060ceb96 100644 --- a/arch/arm64/mm/ptdump.c +++ b/arch/arm64/mm/ptdump.c @@ -278,9 +278,24 @@ void note_page_pgd(struct ptdump_state *pt_st, unsigned long addr, pgd_t pgd) void note_page_flush(struct ptdump_state *pt_st) { + const struct ptdump_range *range = pt_st->range; + unsigned long end = 0; pte_t pte_zero = {0}; - note_page(pt_st, 0, -1, pte_val(pte_zero)); + while (range->start != range->end) { + end = range->end; + range++; + } + + /* + * Address spaces that end at 1 << 64 have range->end == ULONG_MAX, + * but note_page() expects the exclusive end. In this case adjust end + * to the wraparound value 0. + */ + if (end == ULONG_MAX) + end = 0; + + note_page(pt_st, end, -1, pte_val(pte_zero)); } static void arm64_ptdump_walk_pgd(struct ptdump_state *st, struct mm_struct *mm) -- 2.43.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 2/2] KVM: arm64: ptdump: Flush the last region 2026-07-24 18:54 [PATCH v2 0/2] arm64: ptdump flush fixes Wei-Lin Chang 2026-07-24 18:54 ` [PATCH v2 1/2] arm64: ptdump: Make note_page_flush() range aware Wei-Lin Chang @ 2026-07-24 18:54 ` Wei-Lin Chang 2026-07-25 17:16 ` Dev Jain 1 sibling, 1 reply; 5+ messages in thread From: Wei-Lin Chang @ 2026-07-24 18:54 UTC (permalink / raw) To: linux-arm-kernel, kvmarm, linux-kernel Cc: Marc Zyngier, Oliver Upton, Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon, Anshuman Khandual, Ryan Roberts, Dev Jain, David Hildenbrand (Arm), Matt Fleming, Ard Biesheuvel, Mark Rutland, Sebastian Ene, Vincent Donnefort, Wei-Lin Chang, Sashiko AI Currently the stage-2 ptdump calls note_page() at each leaf entry visit. This simply misses the output of the last region, because note_page() only dumps output when it detects a change in level/prot, or when the walk enters a next marker section. The last region in the guest IPA space with the same level/prot is not dumped since there is no change after it. Call note_page_flush() to dump the final region. note_page_flush() expects ptdump_state.range[] to be initialized to the range of the address space, so also do that. Also change the second marker's start address to ULONG_MAX so we never cross it. This avoids dumping redundant marker names (which are NULL), and advancing beyond the end of the marker array. Fixes: 7c4f73548ed1 ("KVM: arm64: Register ptdump with debugfs on guest creation") Reported-by: Sashiko AI <sashiko-bot@kernel.org> Closes: https://lore.kernel.org/kvmarm/20260630122758.891011F00A3A@smtp.kernel.org/ Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com> --- arch/arm64/kvm/ptdump.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c index c9140e22abcf..222577163d2b 100644 --- a/arch/arm64/kvm/ptdump.c +++ b/arch/arm64/kvm/ptdump.c @@ -130,7 +130,7 @@ static struct kvm_ptdump_guest_state *kvm_ptdump_parser_create(struct kvm_s2_mmu } st->ipa_marker[0].name = "Guest IPA"; - st->ipa_marker[1].start_address = BIT(pgtable->ia_bits); + st->ipa_marker[1].start_address = ULONG_MAX; st->mmu = mmu; return st; @@ -148,18 +148,26 @@ static int kvm_ptdump_guest_show(struct seq_file *m, void *unused) .flags = KVM_PGTABLE_WALK_LEAF, }; + guard(write_lock)(&kvm->mmu_lock); st->parser_state = (struct ptdump_pg_state) { .marker = &st->ipa_marker[0], .level = -1, .pg_level = &st->level[0], .seq = m, + .ptdump = { + .range = (struct ptdump_range[]){ + {0, BIT(mmu->pgt->ia_bits)}, + {0, 0} + } + } }; - write_lock(&kvm->mmu_lock); ret = kvm_pgtable_walk(mmu->pgt, 0, BIT(mmu->pgt->ia_bits), &walker); - write_unlock(&kvm->mmu_lock); + if (ret) + return ret; + note_page_flush(&st->parser_state.ptdump); - return ret; + return 0; } static int kvm_ptdump_guest_open(struct inode *m, struct file *file) -- 2.43.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] KVM: arm64: ptdump: Flush the last region 2026-07-24 18:54 ` [PATCH v2 2/2] KVM: arm64: ptdump: Flush the last region Wei-Lin Chang @ 2026-07-25 17:16 ` Dev Jain 2026-07-25 17:28 ` Marc Zyngier 0 siblings, 1 reply; 5+ messages in thread From: Dev Jain @ 2026-07-25 17:16 UTC (permalink / raw) To: Wei-Lin Chang, linux-arm-kernel, kvmarm, linux-kernel Cc: Marc Zyngier, Oliver Upton, Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon, Anshuman Khandual, Ryan Roberts, David Hildenbrand (Arm), Matt Fleming, Ard Biesheuvel, Mark Rutland, Sebastian Ene, Vincent Donnefort, Sashiko AI On 25/07/26 12:24 am, Wei-Lin Chang wrote: > Currently the stage-2 ptdump calls note_page() at each leaf entry visit. > This simply misses the output of the last region, because note_page() > only dumps output when it detects a change in level/prot, or when the > walk enters a next marker section. The last region in the guest IPA > space with the same level/prot is not dumped since there is no change > after it. > > Call note_page_flush() to dump the final region. note_page_flush() > expects ptdump_state.range[] to be initialized to the range of the > address space, so also do that. > > Also change the second marker's start address to ULONG_MAX so we never > cross it. This avoids dumping redundant marker names (which are NULL), > and advancing beyond the end of the marker array. > > Fixes: 7c4f73548ed1 ("KVM: arm64: Register ptdump with debugfs on guest creation") > Reported-by: Sashiko AI <sashiko-bot@kernel.org> > Closes: https://lore.kernel.org/kvmarm/20260630122758.891011F00A3A@smtp.kernel.org/ > Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com> > --- > arch/arm64/kvm/ptdump.c | 16 ++++++++++++---- > 1 file changed, 12 insertions(+), 4 deletions(-) > > diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c > index c9140e22abcf..222577163d2b 100644 > --- a/arch/arm64/kvm/ptdump.c > +++ b/arch/arm64/kvm/ptdump.c > @@ -130,7 +130,7 @@ static struct kvm_ptdump_guest_state *kvm_ptdump_parser_create(struct kvm_s2_mmu > } > > st->ipa_marker[0].name = "Guest IPA"; > - st->ipa_marker[1].start_address = BIT(pgtable->ia_bits); > + st->ipa_marker[1].start_address = ULONG_MAX; > > st->mmu = mmu; > return st; > @@ -148,18 +148,26 @@ static int kvm_ptdump_guest_show(struct seq_file *m, void *unused) > .flags = KVM_PGTABLE_WALK_LEAF, > }; > > + guard(write_lock)(&kvm->mmu_lock); > st->parser_state = (struct ptdump_pg_state) { > .marker = &st->ipa_marker[0], > .level = -1, > .pg_level = &st->level[0], > .seq = m, > + .ptdump = { > + .range = (struct ptdump_range[]){ > + {0, BIT(mmu->pgt->ia_bits)}, > + {0, 0} > + } I am having a real hard time reading that indentation :) you could make it look like what we have currently in ptdump_walk(). The code looks sensible to me. I have also tested by booting a Linux VM inside a Linux VM on a Mac, and I see the stage2 ptdump prints the last range upto the ia_bits correctly. So with the nit addressed above: Reviewed-by: Dev Jain <dev.jain@arm.com> Tested-by: Dev Jain <dev.jain@arm.com> > + } > }; > > - write_lock(&kvm->mmu_lock); > ret = kvm_pgtable_walk(mmu->pgt, 0, BIT(mmu->pgt->ia_bits), &walker); > - write_unlock(&kvm->mmu_lock); > + if (ret) > + return ret; > + note_page_flush(&st->parser_state.ptdump); > > - return ret; > + return 0; > } > > static int kvm_ptdump_guest_open(struct inode *m, struct file *file) ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] KVM: arm64: ptdump: Flush the last region 2026-07-25 17:16 ` Dev Jain @ 2026-07-25 17:28 ` Marc Zyngier 0 siblings, 0 replies; 5+ messages in thread From: Marc Zyngier @ 2026-07-25 17:28 UTC (permalink / raw) To: Dev Jain Cc: Wei-Lin Chang, linux-arm-kernel, kvmarm, linux-kernel, Oliver Upton, Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon, Anshuman Khandual, Ryan Roberts, David Hildenbrand (Arm), Matt Fleming, Ard Biesheuvel, Mark Rutland, Sebastian Ene, Vincent Donnefort, Sashiko AI On Sat, 25 Jul 2026 18:16:37 +0100, Dev Jain <dev.jain@arm.com> wrote: > > > > On 25/07/26 12:24 am, Wei-Lin Chang wrote: > > Currently the stage-2 ptdump calls note_page() at each leaf entry visit. > > This simply misses the output of the last region, because note_page() > > only dumps output when it detects a change in level/prot, or when the > > walk enters a next marker section. The last region in the guest IPA > > space with the same level/prot is not dumped since there is no change > > after it. > > > > Call note_page_flush() to dump the final region. note_page_flush() > > expects ptdump_state.range[] to be initialized to the range of the > > address space, so also do that. > > > > Also change the second marker's start address to ULONG_MAX so we never > > cross it. This avoids dumping redundant marker names (which are NULL), > > and advancing beyond the end of the marker array. > > > > Fixes: 7c4f73548ed1 ("KVM: arm64: Register ptdump with debugfs on guest creation") > > Reported-by: Sashiko AI <sashiko-bot@kernel.org> > > Closes: https://lore.kernel.org/kvmarm/20260630122758.891011F00A3A@smtp.kernel.org/ > > Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com> > > --- > > arch/arm64/kvm/ptdump.c | 16 ++++++++++++---- > > 1 file changed, 12 insertions(+), 4 deletions(-) > > > > diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c > > index c9140e22abcf..222577163d2b 100644 > > --- a/arch/arm64/kvm/ptdump.c > > +++ b/arch/arm64/kvm/ptdump.c > > @@ -130,7 +130,7 @@ static struct kvm_ptdump_guest_state *kvm_ptdump_parser_create(struct kvm_s2_mmu > > } > > > > st->ipa_marker[0].name = "Guest IPA"; > > - st->ipa_marker[1].start_address = BIT(pgtable->ia_bits); > > + st->ipa_marker[1].start_address = ULONG_MAX; > > > > st->mmu = mmu; > > return st; > > @@ -148,18 +148,26 @@ static int kvm_ptdump_guest_show(struct seq_file *m, void *unused) > > .flags = KVM_PGTABLE_WALK_LEAF, > > }; > > > > + guard(write_lock)(&kvm->mmu_lock); > > st->parser_state = (struct ptdump_pg_state) { > > .marker = &st->ipa_marker[0], > > .level = -1, > > .pg_level = &st->level[0], > > .seq = m, > > + .ptdump = { > > + .range = (struct ptdump_range[]){ > > + {0, BIT(mmu->pgt->ia_bits)}, > > + {0, 0} > > + } > > I am having a real hard time reading that indentation :) you > could make it look like what we have currently in ptdump_walk(). This patch: .ptdump = { .range = (struct ptdump_range[]){ {0, BIT(mmu->pgt->ia_bits)}, {0, 0} } } ptdump_walk(): .ptdump = { [...] .range = (struct ptdump_range[]){ {info->base_addr, end}, {0, 0} } } Zero difference in indentation. Consider using a better email client, or look at the applied patches. M. -- Jazz isn't dead. It just smells funny. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-25 17:27 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-24 18:54 [PATCH v2 0/2] arm64: ptdump flush fixes Wei-Lin Chang 2026-07-24 18:54 ` [PATCH v2 1/2] arm64: ptdump: Make note_page_flush() range aware Wei-Lin Chang 2026-07-24 18:54 ` [PATCH v2 2/2] KVM: arm64: ptdump: Flush the last region Wei-Lin Chang 2026-07-25 17:16 ` Dev Jain 2026-07-25 17:28 ` Marc Zyngier
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox