[PATCH 1/2] arm64: mm: dump: make page table dumping reusable

Huang Shijie shijie.huang at arm.com
Wed Jun 1 18:48:13 PDT 2016


On Wed, Jun 01, 2016 at 10:58:18AM +0100, Mark Rutland wrote:
> On Wed, Jun 01, 2016 at 11:01:35AM +0800, Huang Shijie wrote:
> > On Tue, May 31, 2016 at 02:49:01PM +0100, Mark Rutland wrote:
> > > +struct ptdump_info {
> > > +	struct mm_struct		*mm;
> > > +	const struct addr_marker	*markers;
> > > +	unsigned long			base_addr;
> > > +	unsigned long			max_addr;
> > > +};
> > > +
> > > +int ptdump_register(struct ptdump_info *info, const char *name);
> > Since we export this to other page tables,  I guess the @base_addr in
> > the ptdump_info{} may not equal to the VA_START.
> 
> Yes, that is the intent.
> 
> The only requirement is that this is only VA_START or 0, as these are the only
> addresses aligned to VA_BITS which actually correspond to regions page tables
> can cover.
> 
> > But the current dump.c does _NOT_ use the @start address been
> > passed in, it use the 0 as the start address for the walk_pgd/walk_pud/walk_pmd/walk_pte.
> 
> Yes, this is deliberate. The trick is that start must be aligned to
> VA_BITS, and the page table accessors do the right thing, masking out
yes, this is the trick...

> bits which do not matter for their respective indices, e.g.
> 
> #define pgd_index(addr)			(((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
> #define pgd_offset_raw(pgd, addr)	((pgd) + pgd_index(addr))
> #define pgd_offset(mm, addr)		(pgd_offset_raw((mm)->pgd, (addr)))
> 
> This allows us to either provide a virtual address to the accessors
> (which can be in the low or high half), or an offset relative to the
> start of each pgd, pud, pmd, or pte.
> 
> So for walk_pgd:
> 
> static void walk_pgd(struct pg_state *st, struct mm_struct *mm, unsigned long start)
> {
> 	pgd_t *pgd = pgd_offset(mm, 0UL);
> 	unsigned i;
> 	unsigned long addr;
> 
> 	for (i = 0; i < PTRS_PER_PGD; i++, pgd++) {
> 		addr = start + i * PGDIR_SIZE;
> 		if (pgd_none(*pgd)) {
> 			note_page(st, addr, 1, pgd_val(*pgd));
> 		} else {
> 			BUG_ON(pgd_bad(*pgd));
> 			walk_pud(st, pgd, addr);
> 		}
> 	}
> }
> 
> Here, the 0UL we pass to pgd_offset is the offset from the start of the
> pgd, not the absolute virtual address. 
> 
> In the loop, we generate the virtual address each pgd_t corresponds to,
> and we pass this down to note_page or walk_pud as appropriate. We do
> likewise in walk_pud, walk_pmd, and walk_pte.
> 
> So when we reach note_page, we should always have the right virtual
> address in the addr parameter.
> 
> > It is wrong in logic, since the start address is VA_START, the code gets
> > the right result coincidentally.
> 
> As above, I think that the logic is correct.
> 
> Hopefully the explanation above allays your fears?
Thanks for the explanation.

Huang Shijie




More information about the linux-arm-kernel mailing list