KVM: arm64: ptdump: Initialize parser_state before pgtable walk
PATCH 1/1 KVM: arm64: ptdump: Initialize parser_state before pgtable walk
From: "Zenghui Yu (Huawei)" <[email protected]>
If we go through the "need a bigger buffer" path in seq_read_iter(), which is likely to happen as we're dumping page tables, we will pass the populated-by-last-run st::parser_state to kvm_pgtable_walk()/kvm_ptdump_visitor(). As a result, the output of stage2_page_tables on my box looks like
0x0000000240000000-0x0000000000000000 17179869175G 1
0x0000000000000000-0x0000000000200000 2M 2 R px ux AF BLK
0x0000000000200000-0x0000000040000000 1022M 2
0x0000000040000000-0x0000000040200000 2M 2 R W PXNUXN AF BLK
[...]
Fix it by always initializing st::parser_state before starting a new pgtable walk.
Besides, remove st::range as it's not used by note_page(); remove the explicit initialization of parser_state::start_address as it will be initialized in note_page() anyway.
--- arch/arm64/kvm/ptdump.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-)
arch/arm64/kvm/ptdump.c +7 -13
@@ -22,7 +22,6 @@ struct kvm_ptdump_guest_state {struct ptdump_pg_state parser_state;struct addr_marker ipa_marker[MARKERS_LEN ];struct ptdump_pg_level level[KVM_PGTABLE_MAX_LEVELS ]; -struct ptdump_range range[MARKERS_LEN ]; };static const struct ptdump_prot_bits stage2_pte_bits[] = {
@@ -131,16 +130,7 @@ static struct kvm_ptdump_guest_state *kvm_ptdump_parser_create(struct kvm *kvm) st->ipa_marker[0 ].name ="Guest IPA" ; st->ipa_marker[1 ].start_address =BIT (pgtable->ia_bits); - st->range[0 ].end =BIT (pgtable->ia_bits); - st->kvm = kvm; - st->parser_state = (struct ptdump_pg_state ) { - .marker = &st->ipa_marker[0 ], - .level =-1 , - .pg_level = &st->level[0 ], - .ptdump.range = &st->range[0 ], - .start_address =0 , - };return st; }
@@ -151,14 +141,18 @@ static int kvm_ptdump_guest_show(struct seq_file *m, void *unused)struct kvm_ptdump_guest_state *st = m->private;struct kvm *kvm = st->kvm;struct kvm_s2_mmu *mmu = &kvm->arch.mmu; -struct ptdump_pg_state *parser_state = &st->parser_state;struct kvm_pgtable_walker walker = (struct kvm_pgtable_walker ) { .cb = kvm_ptdump_visitor, - .arg = parser_state, + .arg = &st->parser_state, .flags =KVM_PGTABLE_WALK_LEAF , }; - parser_state->seq = m; + st->parser_state = (struct ptdump_pg_state ) { + .marker = &st->ipa_marker[0 ], + .level =-1 , + .pg_level = &st->level[0 ], + .seq = m, + };write_lock (&kvm->mmu_lock); ret =kvm_pgtable_walk (mmu->pgt,0 ,BIT (mmu->pgt->ia_bits), &walker);
Signature · 1 line
2.53.0
Quoted 6 lines · Zenghui Yu
If we go through the "need a bigger buffer" path in
seq_read_iter(), which is likely to happen as we're dumping page tables, we will pass the populated-by-last-runst::parser_stateto kvm_pgtable_walk()/kvm_ptdump_visitor(). As a result, the output ofstage2_page_tableson my box looks like
Quoted 7 lines
0x0000000240000000-0x0000000000000000 17179869175G 1
0x0000000000000000-0x0000000000200000 2M 2 R px ux AF BLK
0x0000000000200000-0x0000000040000000 1022M 2
0x0000000040000000-0x0000000040200000 2M 2 R W PXNUXN AF BLK
[...][...]
Applied to next, thanks!
[1/1] KVM: arm64: ptdump: Initialize parser_state before pgtable walk
commit: 570428601ba506e76c265a65626524ef3c5cbc04
Cheers,
M.
Signature · 1 line
Without deviation from the norm, progress is not possible.