[PATCH v3] ptdump: add intermediate directory support

Jesse Taube mr.bossman075 at gmail.com
Tue May 21 09:54:34 PDT 2024



On 4/30/24 12:05, Maxwell Bland wrote:
> Add an optional note_non_leaf parameter to ptdump, causing note_page to
> be called on non-leaf descriptors. Implement this functionality on arm64
> by printing table descriptors along with table-specific permission sets.
> 
> For arm64, break (1) the uniform number of columns for each descriptor,
> and (2) the coalescing of large PTE regions, which are now split up by
> PMD. This is a "good" thing since it makes the behavior and protection
> bits set on page tables, such as PXNTable, more explicit.
> 
> Before:
> 0xffff008440210000-0xffff008440400000 1984K PTE ro NX SHD AF NG UXN M...
> 0xffff008440400000-0xffff008441c00000 24M PMD ro NX SHD AF NG BLK UXN...
> 0xffff008441c00000-0xffff008441dc0000 1792K PTE ro NX SHD AF NG UXN M...
> 0xffff008441dc0000-0xffff00844317b000 20204K PTE RW NX SHD AF NG UXN ...
> 
> After (tabulation omitted and spaces condensed):
> 0xffff0fb640200000-0xffff0fb640400000 2M PMD TBL RW x NXTbl UXNTbl ME...
> 0xffff0fb640200000-0xffff0fb640210000 64K PTE RW NX SHD AF NG UXN MEM...
> 0xffff0fb640210000-0xffff0fb640400000 1984K PTE ro NX SHD AF NG UXN M...
> 0xffff0fb640400000-0xffff0fb641c00000 24M PMD BLK ro SHD AF NG NX UXN...
> 0xffff0fb641c00000-0xffff0fb641e00000 2M PMD TBL RW x NXTbl UXNTbl ME...
> 0xffff0fb641c00000-0xffff0fb641dc0000 1792K PTE ro NX SHD AF NG UXN M...
> 0xffff0fb641dc0000-0xffff0fb641e00000 256K PTE RW NX SHD AF NG UXN ME...
> 
> v3:
>    - Added tabulation to delineate entries
>    - Fixed formatting issues with mailer and rebased to mm/linus
> 
> v2:
>    - Rebased onto linux-next/akpm (the incorrect branch)

Typically the patch versions go in the additional comments section under 
the ---
https://www.kernel.org/doc/html/v4.13/process/submitting-patches.html#the-canonical-patch-format

> 
> Signed-off-by: Maxwell Bland <mbland at motorola.com>

When you reply the email client(and git send-email???) seems to send it 
twice?
Very odd im suprised the server didnt filter the dup.
https://lore.kernel.org/all/ZjIwiFa3CMxxtAZ1@arm.com/

> ---
> Thank you again to the maintainers for your review of this patch.
> 
> To Andrew Morton, I apologize for the malformatted patches last week.It
> will hopefully never happen again. I have tested mailing this patch to
> myself and have confirmed it cleanly merges to mm/linus.
> 
>   Documentation/arch/arm64/ptdump.rst | 184 +++++++++++++---------

Typicaly docs are seperated into a seperate commit and sent as a set.

>   arch/arm64/mm/ptdump.c              | 230 +++++++++++++++++++++++++---

As said by Catalin anything that can be seperated into smaller patches 
should be.

>   include/linux/ptdump.h              |   1 +
>   mm/ptdump.c                         |  13 ++
>   4 files changed, 332 insertions(+), 96 deletions(-)
> 
> diff --git a/Documentation/arch/arm64/ptdump.rst b/Documentation/arch/arm64/ptdump.rst
> index 5dcfc5d7cddf..350eea06300e 100644
> --- a/Documentation/arch/arm64/ptdump.rst
> +++ b/Documentation/arch/arm64/ptdump.rst
> @@ -2,25 +2,24 @@
>   Kernel page table dump
>   ======================
>   
> -ptdump is a debugfs interface that provides a detailed dump of the
> -kernel page tables. It offers a comprehensive overview of the kernel
> -virtual memory layout as well as the attributes associated with the
> -various regions in a human-readable format. It is useful to dump the
> -kernel page tables to verify permissions and memory types. Examining the
> -page table entries and permissions helps identify potential security
> -vulnerabilities such as mappings with overly permissive access rights or
> -improper memory protections.
> +ptdump is a debugfs interface that provides a detailed dump of the kernel page
> +tables. It offers a comprehensive overview of the kernel virtual memory layout
> +as well as the attributes associated with the various regions in a
> +human-readable format. It is useful to dump the kernel page tables to verify
> +permissions and memory types. Examining the page table entries and permissions
> +helps identify potential security vulnerabilities such as mappings with overly
> +permissive access rights or improper memory protections.
>   
> -Memory hotplug allows dynamic expansion or contraction of available
> -memory without requiring a system reboot. To maintain the consistency
> -and integrity of the memory management data structures, arm64 makes use
> -of the ``mem_hotplug_lock`` semaphore in write mode. Additionally, in
> -read mode, ``mem_hotplug_lock`` supports an efficient implementation of
> -``get_online_mems()`` and ``put_online_mems()``. These protect the
> -offlining of memory being accessed by the ptdump code.
> +Memory hotplug allows dynamic expansion or contraction of available memory
> +without requiring a system reboot. To maintain the consistency and integrity of
> +the memory management data structures, arm64 makes use of the
> +``mem_hotplug_lock`` semaphore in write mode. Additionally, in read mode,
> +``mem_hotplug_lock`` supports an efficient implementation of
> +``get_online_mems()`` and ``put_online_mems()``. These protect the offlining of
> +memory being accessed by the ptdump code.
>   
> -In order to dump the kernel page tables, enable the following
> -configurations and mount debugfs::
> +In order to dump the kernel page tables, enable the following configurations
> +and mount debugfs::
>   
>    CONFIG_GENERIC_PTDUMP=y
>    CONFIG_PTDUMP_CORE=y
> @@ -29,68 +28,101 @@ configurations and mount debugfs::
>    mount -t debugfs nodev /sys/kernel/debug
>    cat /sys/kernel/debug/kernel_page_tables
>   
> -On analysing the output of ``cat /sys/kernel/debug/kernel_page_tables``
> -one can derive information about the virtual address range of the entry,
> -followed by size of the memory region covered by this entry, the
> -hierarchical structure of the page tables and finally the attributes
> -associated with each page. The page attributes provide information about
> -access permissions, execution capability, type of mapping such as leaf
> -level PTE or block level PGD, PMD and PUD, and access status of a page
> -within the kernel memory. Assessing these attributes can assist in
> -understanding the memory layout, access patterns and security
> -characteristics of the kernel pages.
> +On analysing the output of ``cat /sys/kernel/debug/kernel_page_tables`` one can
> +derive information about the virtual address range of a contiguous group of
> +page table entries, followed by size of the memory region covered by this
> +group, the hierarchical structure of the page tables and finally the attributes
> +associated with each page in the group. Groups are broken up either according
> +to a change in attributes or by parent descriptor, such as a PMD. Note that the
> +set of attributes, and therefore formatting, is not equivalent between entry
> +types. For example, PMD entries have a separate set of attributes from leaf
> +level PTE entries, because they support both the UXNTable and PXNTable
> +permission bits.
> +
> +The page attributes provide information about access permissions, execution
> +capability, type of mapping such as leaf level PTE or block level PGD, PMD and
> +PUD, and access status of a page within the kernel memory. Non-PTE block or
> +page level entries are denoted with either "BLK" or "TBL", respectively.
> +Assessing these attributes can assist in understanding the memory layout,
> +access patterns and security characteristics of the kernel pages.
>   
>   Kernel virtual memory layout example::
>   
> - start address        end address         size             attributes
> - +---------------------------------------------------------------------------------------+
> - | ---[ Linear Mapping start ]---------------------------------------------------------- |
> - | ..................                                                                    |
> - | 0xfff0000000000000-0xfff0000000210000  2112K PTE RW NX SHD AF  UXN  MEM/NORMAL-TAGGED |
> - | 0xfff0000000210000-0xfff0000001c00000 26560K PTE ro NX SHD AF  UXN  MEM/NORMAL        |
> - | ..................                                                                    |
> - | ---[ Linear Mapping end ]------------------------------------------------------------ |
> - +---------------------------------------------------------------------------------------+
> - | ---[ Modules start ]----------------------------------------------------------------- |
> - | ..................                                                                    |
> - | 0xffff800000000000-0xffff800008000000   128M PTE                                      |
> - | ..................                                                                    |
> - | ---[ Modules end ]------------------------------------------------------------------- |
> - +---------------------------------------------------------------------------------------+
> - | ---[ vmalloc() area ]---------------------------------------------------------------- |
> - | ..................                                                                    |
> - | 0xffff800008010000-0xffff800008200000  1984K PTE ro x  SHD AF       UXN  MEM/NORMAL   |
> - | 0xffff800008200000-0xffff800008e00000    12M PTE ro x  SHD AF  CON  UXN  MEM/NORMAL   |
> - | ..................                                                                    |
> - | ---[ vmalloc() end ]----------------------------------------------------------------- |
> - +---------------------------------------------------------------------------------------+
> - | ---[ Fixmap start ]------------------------------------------------------------------ |
> - | ..................                                                                    |
> - | 0xfffffbfffdb80000-0xfffffbfffdb90000    64K PTE ro x  SHD AF  UXN  MEM/NORMAL        |
> - | 0xfffffbfffdb90000-0xfffffbfffdba0000    64K PTE ro NX SHD AF  UXN  MEM/NORMAL        |
> - | ..................                                                                    |
> - | ---[ Fixmap end ]-------------------------------------------------------------------- |
> - +---------------------------------------------------------------------------------------+
> - | ---[ PCI I/O start ]----------------------------------------------------------------- |
> - | ..................                                                                    |
> - | 0xfffffbfffe800000-0xfffffbffff800000    16M PTE                                      |
> - | ..................                                                                    |
> - | ---[ PCI I/O end ]------------------------------------------------------------------- |
> - +---------------------------------------------------------------------------------------+
> - | ---[ vmemmap start ]----------------------------------------------------------------- |
> - | ..................                                                                    |
> - | 0xfffffc0002000000-0xfffffc0002200000     2M PTE RW NX SHD AF  UXN  MEM/NORMAL        |
> - | 0xfffffc0002200000-0xfffffc0020000000   478M PTE                                      |
> - | ..................                                                                    |
> - | ---[ vmemmap end ]------------------------------------------------------------------- |
> - +---------------------------------------------------------------------------------------+
> + start address        end address         size type  leaf    attributes
> + +-----------------------------------------------------------------------------------------------------------------+
> + | ---[ Linear Mapping start ]---                                                                                  |
> + | ...                                                                                                             |
> + | 0xffff0d02c3200000-0xffff0d02c3400000    2M PMD   TBL     RW               x      NXTbl UXNTbl    MEM/NORMAL    |
> + | 0xffff0d02c3200000-0xffff0d02c3218000   96K PTE           ro NX SHD AF NG     UXN    MEM/NORMAL-TAGGED          |
> + | 0xffff0d02c3218000-0xffff0d02c3250000  224K PTE           RW NX SHD AF NG     UXN    MEM/NORMAL-TAGGED          |
> + | 0xffff0d02c3250000-0xffff0d02c33b3000 1420K PTE           ro NX SHD AF NG     UXN    MEM/NORMAL-TAGGED          |
> + | 0xffff0d02c33b3000-0xffff0d02c3400000  308K PTE           RW NX SHD AF NG     UXN    MEM/NORMAL-TAGGED          |
> + | 0xffff0d02c3400000-0xffff0d02c3600000    2M PMD   TBL     RW               x      NXTbl UXNTbl    MEM/NORMAL    |
> + | 0xffff0d02c3400000-0xffff0d02c3600000    2M PTE           RW NX SHD AF NG     UXN    MEM/NORMAL-TAGGED          |
> + | ...                                                                                                             |
> + | 0xffff0d02c3200000-0xffff0d02c3400000    2M PMD   TBL     RW               x      NXTbl UXNTbl    MEM/NORMAL    |
> + | ...                                                                                                             |
> + | ---[ Linear Mapping end ]---                                                                                    |
> + +-----------------------------------------------------------------------------------------------------------------+
> + | ---[ Modules start ]---                                                                                         |
> + | ...                                                                                                             |
> + | 0xffff800000000000-0xffff800000000080 128B PGD   TBL     RW               x     UXNTbl    MEM/NORMAL            |
> + | 0xffff800000000000-0xffff800080000000   2G PUD F BLK     RW               x               MEM/NORMAL            |
> + | ...                                                                                                             |
> + | ---[ Modules end ]---                                                                                           |
> + +-----------------------------------------------------------------------------------------------------------------+
> + | ---[ vmalloc() area ]---                                                                                        |
> + | ...                                                                                                             |
> + | 0xffff800080000000-0xffff8000c0000000   1G PUD   TBL     RW               x     UXNTbl    MEM/NORMAL            |
> + | ...                                                                                                             |
> + | 0xffff800080200000-0xffff800080400000   2M PMD   TBL     RW               x      NXTbl UXNTbl    MEM/NORMAL     |
> + | 0xffff800080200000-0xffff80008022f000 188K PTE           RW NX SHD AF NG     UXN    MEM/NORMAL                  |

It's probably good to add another space between F and BLK to show that F 
is related to the type? Also maybe add docs as to what it means, but I 
may just be dumb and its obvious to others.

> + | 0xffff80008022f000-0xffff800080230000   4K PTE F BLK     RW x                       MEM/NORMAL                  |
> + | 0xffff800080230000-0xffff800080233000  12K PTE           RW NX SHD AF NG     UXN    MEM/NORMAL                  |
> + | 0xffff800080233000-0xffff800080234000   4K PTE F BLK     RW x                       MEM/NORMAL                  |
> + | 0xffff800080234000-0xffff800080237000  12K PTE           RW NX SHD AF NG     UXN    MEM/NORMAL                  |
> + | ...                                                                                                             |
> + | 0xffff800080400000-0xffff800084000000  60M PMD F BLK     RW               x      x     x         MEM/NORMAL     |
> + | ...                                                                                                             |
> + | ---[ vmalloc() end ]---                                                                                         |
> + +-----------------------------------------------------------------------------------------------------------------+
> + | ---[ vmemmap start ]---                                                                                         |
> + | ...                                                                                                             |
> + | 0xfffffe33cb000000-0xfffffe33cc000000  16M PMD   BLK     RW SHD AF NG     NX UXN x     x         MEM/NORMAL     |
> + | 0xfffffe33cc000000-0xfffffe3400000000 832M PMD F BLK     RW               x      x     x         MEM/NORMAL     |
> + | ...                                                                                                             |
> + | ---[ vmemmap end ]---                                                                                           |
> + +-----------------------------------------------------------------------------------------------------------------+
> + | ---[ PCI I/O start ]---                                                                                         |
> + | ...                                                                                                             |
> + | 0xffffffffc0800000-0xffffffffc0810000 64K PTE           RW NX SHD AF NG     UXN    DEVICE/nGnRE                 |
> + | ...                                                                                                             |
> + | ---[ PCI I/O end ]---                                                                                           |
> + +-----------------------------------------------------------------------------------------------------------------+
> + | ---[ Fixmap start ]---                                                                                          |
> + | ...                                                                                                             |
> + | 0xffffffffff5f6000-0xffffffffff5f9000 12K PTE           ro x  SHD AF        UXN    MEM/NORMAL                   |
> + | 0xffffffffff5f9000-0xffffffffff5fa000  4K PTE           ro NX SHD AF NG     UXN    MEM/NORMAL                   |
> + | ...                                                                                                             |
> + | ---[ Fixmap end ]---                                                                                            |
> + +-----------------------------------------------------------------------------------------------------------------+
>   
>   ``cat /sys/kernel/debug/kernel_page_tables`` output::
>   
> - 0xfff0000001c00000-0xfff0000080000000     2020M PTE  RW NX SHD AF   UXN    MEM/NORMAL-TAGGED
> - 0xfff0000080000000-0xfff0000800000000       30G PMD
> - 0xfff0000800000000-0xfff0000800700000        7M PTE  RW NX SHD AF   UXN    MEM/NORMAL-TAGGED
> - 0xfff0000800700000-0xfff0000800710000       64K PTE  ro NX SHD AF   UXN    MEM/NORMAL-TAGGED
> - 0xfff0000800710000-0xfff0000880000000  2089920K PTE  RW NX SHD AF   UXN    MEM/NORMAL-TAGGED
> - 0xfff0000880000000-0xfff0040000000000     4062G PMD
> - 0xfff0040000000000-0xffff800000000000     3964T PGD
> + 0xffff000000000000-0xffff020000000000           2T PGD
> + 0xffff020000000000-0xffff020000000080         128B PGD   TBL     RW               NXTbl UXNTbl    MEM/NORMAL
> +     0xffff020000000000-0xffff023080000000         194G PUD
> +     0xffff023080000000-0xffff0230c0000000           1G PUD   TBL     RW               NXTbl UXNTbl    MEM/NORMAL
> +       0xffff023080000000-0xffff023080200000           2M PMD   TBL     RW               x      NXTbl UXNTbl    MEM/NORMAL
> +         0xffff023080000000-0xffff023080200000           2M PTE           RW NX SHD AF NG     UXN    MEM/NORMAL-TAGGED
> +       0xffff023080200000-0xffff023080400000           2M PMD   TBL     RW               x      NXTbl UXNTbl    MEM/NORMAL
> +         0xffff023080200000-0xffff023080210000          64K PTE           RW NX SHD AF NG     UXN    MEM/NORMAL-TAGGED
> +         0xffff023080210000-0xffff023080400000        1984K PTE           ro NX SHD AF NG     UXN    MEM/NORMAL
> +       0xffff023080400000-0xffff023081c00000          24M PMD   BLK     ro SHD AF NG     NX UXN x     x         MEM/NORMAL
> +       0xffff023081c00000-0xffff023081e00000           2M PMD   TBL     RW               x      NXTbl UXNTbl    MEM/NORMAL
> +         0xffff023081c00000-0xffff023081dd0000        1856K PTE           ro NX SHD AF NG     UXN    MEM/NORMAL
> +         0xffff023081dd0000-0xffff023081e00000         192K PTE           RW NX SHD AF NG     UXN    MEM/NORMAL-TAGGED
> +       0xffff023081e00000-0xffff023082000000           2M PMD   TBL     RW               x      NXTbl UXNTbl    MEM/NORMAL
> +         0xffff023081e00000-0xffff023082000000           2M PTE           RW NX SHD AF NG     UXN    MEM/NORMAL-TAGGED
> +       0xffff023082000000-0xffff023082200000           2M PMD   TBL     RW               x      NXTbl UXNTbl    MEM/NORMAL
> +         0xffff023082000000-0xffff023082200000           2M PTE           RW NX SHD AF NG     UXN    MEM/NORMAL-TAGGED
> diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c
> index 6986827e0d64..bd4f1df0c444 100644
> --- a/arch/arm64/mm/ptdump.c
> +++ b/arch/arm64/mm/ptdump.c
> @@ -24,6 +24,7 @@
>   #include <asm/memory.h>
>   #include <asm/pgtable-hwdef.h>
>   #include <asm/ptdump.h>
> +#include <asm/pgalloc.h>
>   
>   
>   #define pt_dump_seq_printf(m, fmt, args...)	\
> @@ -70,6 +71,11 @@ static const struct prot_bits pte_bits[] = {
>   		.val	= PTE_VALID,
>   		.set	= " ",
>   		.clear	= "F",
> +	}, {
> +		.mask	= PTE_TABLE_BIT,
> +		.val	= PTE_TABLE_BIT,
> +		.set	= "   ",
> +		.clear	= "BLK",
>   	}, {
>   		.mask	= PTE_USER,
>   		.val	= PTE_USER,
> @@ -105,11 +111,6 @@ static const struct prot_bits pte_bits[] = {
>   		.val	= PTE_CONT,
>   		.set	= "CON",
>   		.clear	= "   ",
> -	}, {
> -		.mask	= PTE_TABLE_BIT,
> -		.val	= PTE_TABLE_BIT,
> -		.set	= "   ",
> -		.clear	= "BLK",
>   	}, {
>   		.mask	= PTE_UXN,
>   		.val	= PTE_UXN,
> @@ -143,34 +144,208 @@ static const struct prot_bits pte_bits[] = {
>   	}
>   };
>   
> +static const struct prot_bits pmd_bits[] = {
> +	{
> +		.mask	= PMD_SECT_VALID,
> +		.val	= PMD_SECT_VALID,
> +		.set	= " ",
> +		.clear	= "F",
> +	}, {
> +		.mask	= PMD_TABLE_BIT,
> +		.val	= PMD_TABLE_BIT,
> +		.set	= "TBL",
> +		.clear	= "BLK",
> +	}, {
> +		.mask	= PMD_SECT_USER,
> +		.val	= PMD_SECT_USER,
> +		.set	= "USR",
> +		.clear	= "   ",
> +	}, {
> +		.mask	= PMD_SECT_RDONLY,
> +		.val	= PMD_SECT_RDONLY,
> +		.set	= "ro",
> +		.clear	= "RW",
> +	}, {
> +		.mask	= PMD_SECT_S,
> +		.val	= PMD_SECT_S,
> +		.set	= "SHD",
> +		.clear	= "   ",
> +	}, {
> +		.mask	= PMD_SECT_AF,
> +		.val	= PMD_SECT_AF,
> +		.set	= "AF",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= PMD_SECT_NG,
> +		.val	= PMD_SECT_NG,
> +		.set	= "NG",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= PMD_SECT_CONT,
> +		.val	= PMD_SECT_CONT,
> +		.set	= "CON",
> +		.clear	= "   ",
> +	}, {
> +		.mask	= PMD_SECT_PXN,
> +		.val	= PMD_SECT_PXN,
> +		.set	= "NX",
> +		.clear	= "x ",
> +	}, {
> +		.mask	= PMD_SECT_UXN,
> +		.val	= PMD_SECT_UXN,
> +		.set	= "UXN",
> +		.clear	= "   ",
> +	}, {
> +		.mask	= PMD_TABLE_PXN,
> +		.val	= PMD_TABLE_PXN,
> +		.set	= "NXTbl",
> +		.clear	= "x    ",
> +	}, {
> +		.mask	= PMD_TABLE_UXN,
> +		.val	= PMD_TABLE_UXN,
> +		.set	= "UXNTbl",
> +		.clear	= "x     ",
> +	}, {
> +		.mask	= PTE_GP,
> +		.val	= PTE_GP,
> +		.set	= "GP",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= PMD_ATTRINDX_MASK,
> +		.val	= PMD_ATTRINDX(MT_DEVICE_nGnRnE),
> +		.set	= "DEVICE/nGnRnE",
> +	}, {
> +		.mask	= PMD_ATTRINDX_MASK,
> +		.val	= PMD_ATTRINDX(MT_DEVICE_nGnRE),
> +		.set	= "DEVICE/nGnRE",
> +	}, {
> +		.mask	= PMD_ATTRINDX_MASK,
> +		.val	= PMD_ATTRINDX(MT_NORMAL_NC),
> +		.set	= "MEM/NORMAL-NC",
> +	}, {
> +		.mask	= PMD_ATTRINDX_MASK,
> +		.val	= PMD_ATTRINDX(MT_NORMAL),
> +		.set	= "MEM/NORMAL",
> +	}, {
> +		.mask	= PMD_ATTRINDX_MASK,
> +		.val	= PMD_ATTRINDX(MT_NORMAL_TAGGED),
> +		.set	= "MEM/NORMAL-TAGGED",
> +	}
> +};
> +
> +static const struct prot_bits pud_bits[] = {
> +	{
> +		.mask	= PUD_TYPE_SECT,
> +		.val	= PUD_TYPE_SECT,
> +		.set	= " ",
> +		.clear	= "F",
> +	}, {
> +		.mask	= PUD_TABLE_BIT,
> +		.val	= PUD_TABLE_BIT,
> +		.set	= "TBL",
> +		.clear	= "BLK",
> +	}, {
> +		.mask	= PTE_USER,
> +		.val	= PTE_USER,
> +		.set	= "USR",
> +		.clear	= "   ",
> +	}, {
> +		.mask	= PUD_SECT_RDONLY,
> +		.val	= PUD_SECT_RDONLY,
> +		.set	= "ro",
> +		.clear	= "RW",
> +	}, {
> +		.mask	= PTE_SHARED,
> +		.val	= PTE_SHARED,
> +		.set	= "SHD",
> +		.clear	= "   ",
> +	}, {
> +		.mask	= PTE_AF,
> +		.val	= PTE_AF,
> +		.set	= "AF",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= PTE_NG,
> +		.val	= PTE_NG,
> +		.set	= "NG",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= PTE_CONT,
> +		.val	= PTE_CONT,
> +		.set	= "CON",
> +		.clear	= "   ",
> +	}, {
> +		.mask	= PUD_TABLE_PXN,
> +		.val	= PUD_TABLE_PXN,
> +		.set	= "NXTbl",
> +		.clear	= "x    ",
> +	}, {
> +		.mask	= PUD_TABLE_UXN,
> +		.val	= PUD_TABLE_UXN,
> +		.set	= "UXNTbl",
> +		.clear	= "      ",
> +	}, {
> +		.mask	= PTE_GP,
> +		.val	= PTE_GP,
> +		.set	= "GP",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= PMD_ATTRINDX_MASK,
> +		.val	= PMD_ATTRINDX(MT_DEVICE_nGnRnE),
> +		.set	= "DEVICE/nGnRnE",
> +	}, {
> +		.mask	= PMD_ATTRINDX_MASK,
> +		.val	= PMD_ATTRINDX(MT_DEVICE_nGnRE),
> +		.set	= "DEVICE/nGnRE",
> +	}, {
> +		.mask	= PMD_ATTRINDX_MASK,
> +		.val	= PMD_ATTRINDX(MT_NORMAL_NC),
> +		.set	= "MEM/NORMAL-NC",
> +	}, {
> +		.mask	= PMD_ATTRINDX_MASK,
> +		.val	= PMD_ATTRINDX(MT_NORMAL),
> +		.set	= "MEM/NORMAL",
> +	}, {
> +		.mask	= PMD_ATTRINDX_MASK,
> +		.val	= PMD_ATTRINDX(MT_NORMAL_TAGGED),
> +		.set	= "MEM/NORMAL-TAGGED",
> +	}
> +};
> +
>   struct pg_level {
>   	const struct prot_bits *bits;
>   	char name[4];
>   	int num;
>   	u64 mask;
> +	unsigned long size;
>   };
>   
>   static struct pg_level pg_level[] __ro_after_init = {
>   	{ /* pgd */
>   		.name	= "PGD",
> -		.bits	= pte_bits,
> -		.num	= ARRAY_SIZE(pte_bits),
> +		.bits	= pud_bits,
> +		.num	= ARRAY_SIZE(pud_bits),
> +		.size	= PGD_SIZE
>   	}, { /* p4d */
>   		.name	= "P4D",
> -		.bits	= pte_bits,
> -		.num	= ARRAY_SIZE(pte_bits),
> +		.bits	= pud_bits,
> +		.num	= ARRAY_SIZE(pud_bits),
> +		.size	= P4D_SIZE
>   	}, { /* pud */
>   		.name	= "PUD",
> -		.bits	= pte_bits,
> -		.num	= ARRAY_SIZE(pte_bits),
> +		.bits	= pud_bits,
> +		.num	= ARRAY_SIZE(pud_bits),
> +		.size	= PUD_SIZE
>   	}, { /* pmd */
>   		.name	= "PMD",
> -		.bits	= pte_bits,
> -		.num	= ARRAY_SIZE(pte_bits),
> +		.bits	= pmd_bits,
> +		.num	= ARRAY_SIZE(pmd_bits),
> +		.size	= PMD_SIZE
>   	}, { /* pte */
>   		.name	= "PTE",
>   		.bits	= pte_bits,
>   		.num	= ARRAY_SIZE(pte_bits),
> +		.size	= PAGE_SIZE
>   	},
>   };
>   
> @@ -225,8 +400,9 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
>   		      u64 val)
>   {
>   	struct pg_state *st = container_of(pt_st, struct pg_state, ptdump);
> -	static const char units[] = "KMGTPE";
> +	static const char units[] = "BKMGTPE";

This doesnt seem to be related to your changes is it?

>   	u64 prot = 0;
> +	int i = 0;
>   
>   	/* check if the current level has been folded dynamically */
>   	if ((level == 1 && mm_p4d_folded(st->mm)) ||
> @@ -241,20 +417,33 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
>   		st->current_prot = prot;
>   		st->start_address = addr;
>   		pt_dump_seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
> -	} else if (prot != st->current_prot || level != st->level ||
> -		   addr >= st->marker[1].start_address) {
> +	} else if ((prot != st->current_prot || level != st->level ||
> +		   addr >= st->marker[1].start_address)) {
>   		const char *unit = units;
>   		unsigned long delta;
>   
> +		for (i = 0; i < st->level; i++)
> +			pt_dump_seq_printf(st->seq, "  ");
> +
>   		if (st->current_prot) {
>   			note_prot_uxn(st, addr);
>   			note_prot_wx(st, addr);
>   		}
>   
> -		pt_dump_seq_printf(st->seq, "0x%016lx-0x%016lx   ",
> -				   st->start_address, addr);
> +		/*
> +		 * Entries are coalesced into a single line, so non-leaf
> +		 * entries have no size relative to start_address
> +		 */
> +		if (st->start_address != addr) {
> +			pt_dump_seq_printf(st->seq, "0x%016lx-0x%016lx   ",
> +					   st->start_address, addr);
> +			delta = (addr - st->start_address);
> +		} else {
> +			pt_dump_seq_printf(st->seq, "0x%016lx-0x%016lx   ", addr,
> +					   addr + pg_level[st->level].size);
> +			delta = (pg_level[st->level].size);
> +		}
>   
> -		delta = (addr - st->start_address) >> 10;
>   		while (!(delta & 1023) && unit[1]) {
>   			delta >>= 10;
>   			unit++;
> @@ -301,7 +490,8 @@ void ptdump_walk(struct seq_file *s, struct ptdump_info *info)
>   			.range = (struct ptdump_range[]){
>   				{info->base_addr, end},
>   				{0, 0}
> -			}
> +			},
> +			.note_non_leaf = true
>   		}
>   	};
>   
> diff --git a/include/linux/ptdump.h b/include/linux/ptdump.h
> index 8dbd51ea8626..b3e793a5c77f 100644
> --- a/include/linux/ptdump.h
> +++ b/include/linux/ptdump.h
> @@ -16,6 +16,7 @@ struct ptdump_state {
>   			  int level, u64 val);
>   	void (*effective_prot)(struct ptdump_state *st, int level, u64 val);
>   	const struct ptdump_range *range;
> +	bool note_non_leaf;
>   };
>   
>   bool ptdump_walk_pgd_level_core(struct seq_file *m,
> diff --git a/mm/ptdump.c b/mm/ptdump.c
> index 106e1d66e9f9..97da7a765b22 100644
> --- a/mm/ptdump.c
> +++ b/mm/ptdump.c
> @@ -41,6 +41,9 @@ static int ptdump_pgd_entry(pgd_t *pgd, unsigned long addr,
>   	if (st->effective_prot)
>   		st->effective_prot(st, 0, pgd_val(val));
>   
> +	if (st->note_non_leaf && !pgd_leaf(val))
> +		st->note_page(st, addr, 0, pgd_val(val));
> +
>   	if (pgd_leaf(val)) {
>   		st->note_page(st, addr, 0, pgd_val(val));
>   		walk->action = ACTION_CONTINUE;
> @@ -64,6 +67,9 @@ static int ptdump_p4d_entry(p4d_t *p4d, unsigned long addr,
>   	if (st->effective_prot)
>   		st->effective_prot(st, 1, p4d_val(val));
>   
> +	if (st->note_non_leaf && !p4d_leaf(val))
> +		st->note_page(st, addr, 1, p4d_val(val));
> +
>   	if (p4d_leaf(val)) {
>   		st->note_page(st, addr, 1, p4d_val(val));
>   		walk->action = ACTION_CONTINUE;
> @@ -87,6 +93,9 @@ static int ptdump_pud_entry(pud_t *pud, unsigned long addr,
>   	if (st->effective_prot)
>   		st->effective_prot(st, 2, pud_val(val));
>   
> +	if (st->note_non_leaf && !pud_leaf(val))
> +		st->note_page(st, addr, 2, pud_val(val));
> +
>   	if (pud_leaf(val)) {
>   		st->note_page(st, addr, 2, pud_val(val));
>   		walk->action = ACTION_CONTINUE;
> @@ -108,6 +117,10 @@ static int ptdump_pmd_entry(pmd_t *pmd, unsigned long addr,
>   
>   	if (st->effective_prot)
>   		st->effective_prot(st, 3, pmd_val(val));
> +
> +	if (st->note_non_leaf && !pmd_leaf(val))
> +		st->note_page(st, addr, 3, pmd_val(val));
> +
>   	if (pmd_leaf(val)) {
>   		st->note_page(st, addr, 3, pmd_val(val));
>   		walk->action = ACTION_CONTINUE;
> 
> base-commit: a93289b830ce783955b22fbe5d1274a464c05acf



More information about the linux-arm-kernel mailing list