[PATCH v16 00/25] Generic page walk and ptdump

From: Steven Price
Date: Fri Dec 06 2019 - 08:53:46 EST


Since this series is still in linux-next and causing problems I'm
sending this out before -rc1.

This version adds two new patches over the previous series (v15):
13: mm: pagewalk: Don't lock PTEs for walk_page_range_novma()
14: mm: pagewalk: fix termination condition in walk_pte_range()

Patch 13 solves the conflict with ace88f1018b8 ("mm: pagewalk: Take the
pagetable lock in walk_pte_range()") by not taking the lock for the
_novma() version of the function.

Patch 14 fixes an existing issue with walk_pte_range() whereby if the
end address isn't aligned to PAGE_SIZE the loop will be infinite. This
starts to trigger on some x86 32 bit configurations with the generic
ptdump support because there is a page in the last PMD which means that
the end address is ~0UL.

I've posted these patches separately as I think they do stand alone (and
shouldn't cause bisection problems) - but 13/14 could potentially be
squashed into 12.

Patch 12 ("mm: pagewalk: Allow walking without vma") has also been
updated from v15 to include the p*d_present() check that was posted[1]
after v15 and Andrew squashed into the commit.

Patch 21 ("mm: Add generic ptdump") also has the fix from Qian Cai
squashed in to fix the order of "static const".

[1] https://lore.kernel.org/lkml/16da6118-ac4d-a165-6202-0731a776ac72@xxxxxxx/

Previous description for the series:

Many architectures current have a debugfs file for dumping the kernel
page tables. Currently each architecture has to implement custom
functions for this because the details of walking the page tables used
by the kernel are different between architectures.

This series extends the capabilities of walk_page_range() so that it can
deal with the page tables of the kernel (which have no VMAs and can
contain larger huge pages than exist for user space). A generic PTDUMP
implementation is the implemented making use of the new functionality of
walk_page_range() and finally arm64 and x86 are switch to using it,
removing the custom table walkers.

To enable a generic page table walker to walk the unusual mappings of
the kernel we need to implement a set of functions which let us know
when the walker has reached the leaf entry. After a suggestion from Will
Deacon I've chosen the name p?d_leaf() as this (hopefully) describes
the purpose (and is a new name so has no historic baggage). Some
architectures have p?d_large macros but this is easily confused with
"large pages".

This series ends with a generic PTDUMP implemention for arm64 and x86.

Mostly this is a clean up and there should be very little functional
change. The exceptions are:

* arm64 PTDUMP debugfs now displays pages which aren't present (patch 22).

* arm64 has the ability to efficiently process KASAN pages (which
previously only x86 implemented). This means that the combination of
KASAN and DEBUG_WX is now useable.

Also available as a git tree:
git://linux-arm.org/linux-sp.git walk_page_range/v16

Changes since v15:
https://lore.kernel.org/lkml/20191101140942.51554-1-steven.price@xxxxxxx/
* Rebased onto Linus' tree, which includes the conflicting commit:
ace88f1018b8 ("mm: pagewalk: Take the pagetable lock in walk_pte_range()")
* New patch fixing conflict with above patch
* Squashed in fix for ordering of "static const"
* Squashed in fix checking p*d_present()
* New patch fixing termination condition for walk_pte_range()

Changes since v14:
https://lore.kernel.org/lkml/20191028135910.33253-1-steven.price@xxxxxxx/
* Switch walk_page_range() into two functions, the existing
walk_page_range() now still requires VMAs (and treats areas without a
VMA as a 'hole'). The new walk_page_range_novma() ignores VMAs and
will report the actual page table layout. This fixes the previous
breakage of /proc/<pid>/pagemap
* New patch at the end of the series which reduces the 'level' numbers
by 1 to simplify the code slightly
* Added tags

Changes since v13:
https://lore.kernel.org/lkml/20191024093716.49420-1-steven.price@xxxxxxx/
* Fixed typo in arc definition of pmd_leaf() spotted by the kbuild test
robot
* Added tags

Changes since v12:
https://lore.kernel.org/lkml/20191018101248.33727-1-steven.price@xxxxxxx/
* Correct code format in riscv pud_leaf()/pmd_leaf()
* v12 may not have reached everyone because of mail server problems
(which are now hopefully resolved!)

Changes since v11:
https://lore.kernel.org/lkml/20191007153822.16518-1-steven.price@xxxxxxx/
* Use "-1" as dummy depth parameter in patch 14.

Changes since v10:
https://lore.kernel.org/lkml/20190731154603.41797-1-steven.price@xxxxxxx/
* Rebased to v5.4-rc1 - mainly various updates to deal with the
splitting out of ops from struct mm_walk.
* Deal with PGD_LEVEL_MULT not always being constant on x86.

Changes since v9:
https://lore.kernel.org/lkml/20190722154210.42799-1-steven.price@xxxxxxx/
* Moved generic macros to first page in the series and explained the
macro naming in the commit message.
* mips: Moved macros to pgtable.h as they are now valid for both 32 and 64
bit
* x86: Dropped patch which changed the debugfs output for x86, instead
we have...
* new patch adding 'depth' parameter to pte_hole. This is used to
provide the necessary information to output lines for 'holes' in the
debugfs files
* new patch changing arm64 debugfs output to include holes to match x86
* generic ptdump KASAN handling has been simplified and now works with
CONFIG_DEBUG_VIRTUAL.

Changes since v8:
https://lore.kernel.org/lkml/20190403141627.11664-1-steven.price@xxxxxxx/
* Rename from p?d_large() to p?d_leaf()
* Dropped patches migrating arm64/x86 custom walkers to
walk_page_range() in favour of adding a generic PTDUMP implementation
and migrating arm64/x86 to that instead.
* Rebased to v5.3-rc1

Steven Price (25):
mm: Add generic p?d_leaf() macros
arc: mm: Add p?d_leaf() definitions
arm: mm: Add p?d_leaf() definitions
arm64: mm: Add p?d_leaf() definitions
mips: mm: Add p?d_leaf() definitions
powerpc: mm: Add p?d_leaf() definitions
riscv: mm: Add p?d_leaf() definitions
s390: mm: Add p?d_leaf() definitions
sparc: mm: Add p?d_leaf() definitions
x86: mm: Add p?d_leaf() definitions
mm: pagewalk: Add p4d_entry() and pgd_entry()
mm: pagewalk: Allow walking without vma
mm: pagewalk: Don't lock PTEs for walk_page_range_novma()
mm: pagewalk: fix termination condition in walk_pte_range()
mm: pagewalk: Add test_p?d callbacks
mm: pagewalk: Add 'depth' parameter to pte_hole
x86: mm: Point to struct seq_file from struct pg_state
x86: mm+efi: Convert ptdump_walk_pgd_level() to take a mm_struct
x86: mm: Convert ptdump_walk_pgd_level_debugfs() to take an mm_struct
x86: mm: Convert ptdump_walk_pgd_level_core() to take an mm_struct
mm: Add generic ptdump
x86: mm: Convert dump_pagetables to use walk_page_range
arm64: mm: Convert mm/dump.c to use walk_page_range()
arm64: mm: Display non-present entries in ptdump
mm: ptdump: Reduce level numbers by 1 in note_page()

arch/arc/include/asm/pgtable.h | 1 +
arch/arm/include/asm/pgtable-2level.h | 1 +
arch/arm/include/asm/pgtable-3level.h | 1 +
arch/arm64/Kconfig | 1 +
arch/arm64/Kconfig.debug | 19 +-
arch/arm64/include/asm/pgtable.h | 2 +
arch/arm64/include/asm/ptdump.h | 8 +-
arch/arm64/mm/Makefile | 4 +-
arch/arm64/mm/dump.c | 148 +++-----
arch/arm64/mm/mmu.c | 4 +-
arch/arm64/mm/ptdump_debugfs.c | 2 +-
arch/mips/include/asm/pgtable.h | 5 +
arch/powerpc/include/asm/book3s/64/pgtable.h | 30 +-
arch/riscv/include/asm/pgtable-64.h | 7 +
arch/riscv/include/asm/pgtable.h | 7 +
arch/s390/include/asm/pgtable.h | 2 +
arch/sparc/include/asm/pgtable_64.h | 2 +
arch/x86/Kconfig | 1 +
arch/x86/Kconfig.debug | 20 +-
arch/x86/include/asm/pgtable.h | 10 +-
arch/x86/mm/Makefile | 4 +-
arch/x86/mm/debug_pagetables.c | 8 +-
arch/x86/mm/dump_pagetables.c | 343 +++++--------------
arch/x86/platform/efi/efi_32.c | 2 +-
arch/x86/platform/efi/efi_64.c | 4 +-
drivers/firmware/efi/arm-runtime.c | 2 +-
fs/proc/task_mmu.c | 4 +-
include/asm-generic/pgtable.h | 20 ++
include/linux/pagewalk.h | 42 ++-
include/linux/ptdump.h | 22 ++
mm/Kconfig.debug | 21 ++
mm/Makefile | 1 +
mm/hmm.c | 8 +-
mm/migrate.c | 5 +-
mm/mincore.c | 1 +
mm/pagewalk.c | 145 ++++++--
mm/ptdump.c | 151 ++++++++
37 files changed, 600 insertions(+), 458 deletions(-)
create mode 100644 include/linux/ptdump.h
create mode 100644 mm/ptdump.c

--
2.20.1