lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <7010301b-5258-4972-ac7d-6451debcb5d5@os.amperecomputing.com>
Date: Mon, 10 Nov 2025 15:06:08 -0800
From: Yang Shi <yang@...amperecomputing.com>
To: ryan.roberts@....com, cl@...two.org, catalin.marinas@....com,
 will@...nel.org
Cc: linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org
Subject: Re: [v2 PATCH] arm64: mm: show direct mapping use in /proc/meminfo

Hi Ryan,

Gently ping. Thanks for reviewing the v1 patch. Any comment for this 
version?

Yang


On 10/23/25 2:52 PM, Yang Shi wrote:
> Since commit a166563e7ec3 ("arm64: mm: support large block mapping when
> rodata=full"), the direct mapping may be split on some machines instead
> keeping static since boot. It makes more sense to show the direct mapping
> use in /proc/meminfo than before.
> This patch will make /proc/meminfo show the direct mapping use like the
> below (4K base page size):
> DirectMap4K:	   94792 kB
> DirectMap64K:	  134208 kB
> DirectMap2M:	 1173504 kB
> DirectMap32M:	 5636096 kB
> DirectMap1G:	529530880 kB
>
> Although just the machines which support BBML2_NOABORT can split the
> direct mapping, show it on all machines regardless of BBML2_NOABORT so
> that the users have consistent view in order to avoid confusion.
>
> Although ptdump also can tell the direct map use, but it needs to dump
> the whole kernel page table. It is costly and overkilling. It is also
> in debugfs which may not be enabled by all distros. So showing direct
> map use in /proc/meminfo seems more convenient and has less overhead.
>
> Signed-off-by: Yang Shi <yang@...amperecomputing.com>
> ---
>   arch/arm64/mm/mmu.c | 86 +++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 86 insertions(+)
>
> v2: * Counted in size instead of the number of entries per Ryan
>      * Removed shift array per Ryan
>      * Use lower case "k" per Ryan
>      * Fixed a couple of build warnings reported by kernel test robot
>      * Fixed a couple of poential miscounts
>
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index b8d37eb037fc..7207b55d0046 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -29,6 +29,7 @@
>   #include <linux/mm_inline.h>
>   #include <linux/pagewalk.h>
>   #include <linux/stop_machine.h>
> +#include <linux/proc_fs.h>
>   
>   #include <asm/barrier.h>
>   #include <asm/cputype.h>
> @@ -51,6 +52,17 @@
>   
>   DEFINE_STATIC_KEY_FALSE(arm64_ptdump_lock_key);
>   
> +enum direct_map_type {
> +	PTE,
> +	CONT_PTE,
> +	PMD,
> +	CONT_PMD,
> +	PUD,
> +	NR_DIRECT_MAP_TYPE,
> +};
> +
> +static unsigned long direct_map_size[NR_DIRECT_MAP_TYPE];
> +
>   u64 kimage_voffset __ro_after_init;
>   EXPORT_SYMBOL(kimage_voffset);
>   
> @@ -171,6 +183,45 @@ static void init_clear_pgtable(void *table)
>   	dsb(ishst);
>   }
>   
> +#ifdef CONFIG_PROC_FS
> +void arch_report_meminfo(struct seq_file *m)
> +{
> +	char *size[NR_DIRECT_MAP_TYPE];
> +
> +#if defined(CONFIG_ARM64_4K_PAGES)
> +	size[PTE] = "4k";
> +	size[CONT_PTE] = "64k";
> +	size[PMD] = "2M";
> +	size[CONT_PMD] = "32M";
> +	size[PUD] = "1G";
> +#elif defined(CONFIG_ARM64_16K_PAGES)
> +	size[PTE] = "16k";
> +	size[CONT_PTE] = "2M";
> +	size[PMD] = "32M";
> +	size[CONT_PMD] = "1G";
> +#elif defined(CONFIG_ARM64_64K_PAGES)
> +	size[PTE] = "64k";
> +	size[CONT_PTE] = "2M";
> +	size[PMD] = "512M";
> +	size[CONT_PMD] = "16G";
> +#endif
> +
> +	seq_printf(m, "DirectMap%s:	%8lu kB\n",
> +			size[PTE], direct_map_size[PTE] >> 10);
> +	seq_printf(m, "DirectMap%s:	%8lu kB\n",
> +			size[CONT_PTE],
> +			direct_map_size[CONT_PTE] >> 10);
> +	seq_printf(m, "DirectMap%s:	%8lu kB\n",
> +			size[PMD], direct_map_size[PMD] >> 10);
> +	seq_printf(m, "DirectMap%s:	%8lu kB\n",
> +			size[CONT_PMD],
> +			direct_map_size[CONT_PMD] >> 10);
> +	if (pud_sect_supported())
> +		seq_printf(m, "DirectMap%s:	%8lu kB\n",
> +			size[PUD], direct_map_size[PUD] >> 10);
> +}
> +#endif
> +
>   static void init_pte(pte_t *ptep, unsigned long addr, unsigned long end,
>   		     phys_addr_t phys, pgprot_t prot)
>   {
> @@ -234,6 +285,11 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
>   
>   		init_pte(ptep, addr, next, phys, __prot);
>   
> +		if (pgprot_val(__prot) & PTE_CONT)
> +			direct_map_size[CONT_PTE] += next - addr;
> +		else
> +			direct_map_size[PTE] += next - addr;
> +
>   		ptep += pte_index(next) - pte_index(addr);
>   		phys += next - addr;
>   	} while (addr = next, addr != end);
> @@ -262,6 +318,17 @@ static void init_pmd(pmd_t *pmdp, unsigned long addr, unsigned long end,
>   		    (flags & NO_BLOCK_MAPPINGS) == 0) {
>   			pmd_set_huge(pmdp, phys, prot);
>   
> +			/*
> +			 * It is possible to have mappings allow cont mapping
> +			 * but disallow block mapping. For example,
> +			 * map_entry_trampoline().
> +			 * So we have to increase CONT_PMD and PMD size here
> +			 * to avoid double counting.
> +			 */
> +			if (pgprot_val(prot) & PTE_CONT)
> +				direct_map_size[CONT_PMD] += next - addr;
> +			else
> +				direct_map_size[PMD] += next - addr;
>   			/*
>   			 * After the PMD entry has been populated once, we
>   			 * only allow updates to the permission attributes.
> @@ -368,6 +435,7 @@ static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
>   		    (flags & NO_BLOCK_MAPPINGS) == 0) {
>   			pud_set_huge(pudp, phys, prot);
>   
> +			direct_map_size[PUD] += next - addr;
>   			/*
>   			 * After the PUD entry has been populated once, we
>   			 * only allow updates to the permission attributes.
> @@ -532,9 +600,13 @@ static void split_contpte(pte_t *ptep)
>   {
>   	int i;
>   
> +	direct_map_size[CONT_PTE] -= CONT_PTE_SIZE;
> +
>   	ptep = PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
>   	for (i = 0; i < CONT_PTES; i++, ptep++)
>   		__set_pte(ptep, pte_mknoncont(__ptep_get(ptep)));
> +
> +	direct_map_size[PTE] += CONT_PTE_SIZE;
>   }
>   
>   static int split_pmd(pmd_t *pmdp, pmd_t pmd, gfp_t gfp, bool to_cont)
> @@ -559,8 +631,13 @@ static int split_pmd(pmd_t *pmdp, pmd_t pmd, gfp_t gfp, bool to_cont)
>   	if (to_cont)
>   		prot = __pgprot(pgprot_val(prot) | PTE_CONT);
>   
> +	direct_map_size[PMD] -= PMD_SIZE;
>   	for (i = 0; i < PTRS_PER_PTE; i++, ptep++, pfn++)
>   		__set_pte(ptep, pfn_pte(pfn, prot));
> +	if (to_cont)
> +		direct_map_size[CONT_PTE] += PMD_SIZE;
> +	else
> +		direct_map_size[PTE] += PMD_SIZE;
>   
>   	/*
>   	 * Ensure the pte entries are visible to the table walker by the time
> @@ -576,9 +653,13 @@ static void split_contpmd(pmd_t *pmdp)
>   {
>   	int i;
>   
> +	direct_map_size[CONT_PMD] -= CONT_PMD_SIZE;
> +
>   	pmdp = PTR_ALIGN_DOWN(pmdp, sizeof(*pmdp) * CONT_PMDS);
>   	for (i = 0; i < CONT_PMDS; i++, pmdp++)
>   		set_pmd(pmdp, pmd_mknoncont(pmdp_get(pmdp)));
> +
> +	direct_map_size[PMD] += CONT_PMD_SIZE;
>   }
>   
>   static int split_pud(pud_t *pudp, pud_t pud, gfp_t gfp, bool to_cont)
> @@ -604,8 +685,13 @@ static int split_pud(pud_t *pudp, pud_t pud, gfp_t gfp, bool to_cont)
>   	if (to_cont)
>   		prot = __pgprot(pgprot_val(prot) | PTE_CONT);
>   
> +	direct_map_size[PUD] -= PUD_SIZE;
>   	for (i = 0; i < PTRS_PER_PMD; i++, pmdp++, pfn += step)
>   		set_pmd(pmdp, pfn_pmd(pfn, prot));
> +	if (to_cont)
> +		direct_map_size[CONT_PMD] += PUD_SIZE;
> +	else
> +		direct_map_size[PMD] += PUD_SIZE;
>   
>   	/*
>   	 * Ensure the pmd entries are visible to the table walker by the time


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ