Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Wen Jiang" <jiangwenxiaomi@gmail.com>,
	akpm@linux-foundation.org, catalin.marinas@arm.com,
	linux-mm@kvack.org, urezki@gmail.com, will@kernel.org
Cc: "Xueyuan Chen" <xueyuan.chen21@gmail.com>,
	ajd@linux.ibm.com, anshuman.khandual@arm.com, baohua@kernel.org,
	chleroy@kernel.org, david@kernel.org, dev.jain@arm.com,
	jiangwen6@xiaomi.com, leo.yan@arm.com, maddy@linux.ibm.com,
	mpe@ellerman.id.au, npiggin@gmail.com, rppt@kernel.org,
	ryan.roberts@arm.com
Subject: Re: [PATCH v11 10/10] mm/vmalloc: align vm_area so vmap() can batch mappings
Date: Wed, 04 Nov 2026 10:19:03 +0000	[thread overview]
Message-ID: <sashiko-outbox-197082@kernel.org> (raw)
In-Reply-To: <20261103101658.766905-11-jiangwenxiaomi@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] mm/vmalloc: out-of-bounds physical mapping in vmap() across PMD boundary
--

commit bba985c9d433d420f66d2ffcfeb47090bbcf7552
Author: Barry Song (Xiaomi) <baohua@kernel.org>

mm/vmalloc: align vm_area so vmap() can batch mappings

This commit aligns the virtual address area allocated for vmap() to PMD_SIZE
or the architecture-supported PTE batch shift so that contiguous pages can be
mapped in batches.

> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index 42b3addd20f98..e15bcef804fc3 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c

[ ... ]

> @@ -3692,6 +3700,30 @@ static int vmap_pages_range_batched(unsigned long addr, unsigned long end,
>  	return err;
>  }
>  
> +static struct vm_struct *vmap_get_aligned_vm_area(unsigned long size,
> +		unsigned long flags, pgprot_t prot, const void *caller)
> +{
> +	struct vm_struct *vm_area;
> +	unsigned int shift;
> +
> +	if (arch_vmap_pmd_supported(prot) && size >= PMD_SIZE) {
> +		vm_area = __get_vm_area_node_aligned_caller(size, PMD_SIZE,
> +				flags, caller);
> +		if (vm_area)
> +			return vm_area;
> +	}
> +
> +	shift = arch_vmap_pte_supported_shift(size);
> +	if (shift > PAGE_SHIFT) {
> +		vm_area = __get_vm_area_node_aligned_caller(size, 1UL << shift,
> +				flags, caller);
> +		if (vm_area)
> +			return vm_area;
> +	}

[Severity: Critical]
Can this cause vmap() to map out-of-bounds physical pages across a PMD
boundary on arm64 when pages[] contains multiple physically discontiguous
chunks that share a mapping shift larger than CONT_PTE_SHIFT?

In vmap_get_aligned_vm_area(), when size < PMD_SIZE (for example, a 1MB vmap
composed of two 512KB order-7 chunks on 4K-page arm64, or an 8MB vmap composed
of two 4MB order-8 chunks on 16K-page arm64 where PMD_SIZE is 32MB), or when
the PMD_SIZE-aligned allocation falls back, the virtual range is only aligned
to 1UL << arch_vmap_pte_supported_shift(size), which is CONT_PTE_SIZE on
arm64. The same alignment also occurs for batch_start if a PMD-aligned vmap
starts with a CONT_PTE_SIZE chunk followed by larger chunks.

In vmap_pages_range_batched(), get_vmap_mapping_order() can return an order
where shift > CONT_PTE_SHIFT, and consecutive discontiguous chunks with the
same shift are coalesced into a single walk:

mm/vmalloc.c:vmap_pages_range_batched() {
	for (unsigned int i = 0; i < nr_pages; ) {
		unsigned int shift = PAGE_SHIFT +
			get_vmap_mapping_order(pages + i, prot, nr_pages - i);

		if (!i)
			prev_shift = shift;

		if (shift != prev_shift) {
			err = vmap_pages_range_noflush_walk(batch_start, batch_end,
					prot, pages + batch_idx, prev_shift);
			...
		}
		...
		batch_end += 1UL << shift;
		i += 1U << (shift - PAGE_SHIFT);
	}
}

When [batch_start, batch_end) crosses a PMD boundary at an offset M into the
first chunk (where 0 < M < (1UL << prev_shift) and M is a multiple of
CONT_PTE_SIZE), vmap_pages_pmd_range() splits the walk at pmd_addr_end(addr,
end). The first PMD maps the initial M bytes of chunk 0 and advances *nr to
M >> PAGE_SHIFT.

At the start of the next PMD (addr = PMD_BOUNDARY), *nr points M bytes into
chunk 0 (physical address PA_0 + M), leaving only (1UL << prev_shift) - M
contiguous bytes in chunk 0 before pages[] switches to the discontiguous
physical address of chunk 1. However, vmap_pages_pte_range() still passes the
full shift = prev_shift to vmap_set_ptes():

mm/vmalloc.c:vmap_pages_pte_range() {
	do {
		struct page *page = pages[*nr];
		...
		pfn = page_to_pfn(page);
		size = vmap_set_ptes(pte, addr, end, pfn, prot, shift);
		nr_pages = PFN_DOWN(size);
	} while (pte += nr_pages, *nr += nr_pages, addr += size, addr != end);
}

Because addr (at PMD_BOUNDARY) and PFN_PHYS(pfn) (at PA_0 + M) are both
aligned to CONT_PTE_SIZE, and end - addr covers the coalesced second chunk,
arch_vmap_pte_range_map_size() returns the full 1UL << prev_shift:

arch/arm64/include/asm/vmalloc.h:arch_vmap_pte_range_map_size() {
	if (!IS_ALIGNED(addr, CONT_PTE_SIZE))
		return PAGE_SIZE;

	if (!IS_ALIGNED(PFN_PHYS(pfn), CONT_PTE_SIZE))
		return PAGE_SIZE;

	size = min(end - addr, 1UL << max_page_shift);
	size = round_down(size, CONT_PTE_SIZE);
	return size;
}

Doesn't vmap_pte_set_huge() then map 1UL << prev_shift contiguous physical
bytes starting at PA_0 + M, overrunning the end of chunk 0 by M bytes into
unowned physical memory while advancing *nr past the first M bytes of chunk 1?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261103101658.766905-1-jiangwenxiaomi@gmail.com?part=10


      reply	other threads:[~2026-11-04 10:19 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-03 10:16 [PATCH v11 00/10] mm/vmalloc: Speed up ioremap, vmalloc and vmap with contiguous memory Wen Jiang
2026-11-03 10:16 ` [PATCH v11 01/10] arm64/mm: add vmap_pte_set_huge() and vmap_pte_clear_huge() Wen Jiang
2026-11-03 10:16 ` [PATCH v11 02/10] powerpc/8xx: add vmap_pte_set_huge() Wen Jiang
2026-11-03 10:16 ` [PATCH v11 03/10] mm/vmalloc: use vmap_pte_set_huge()/vmap_pte_clear_huge() for PTE-level block mappings Wen Jiang
2026-11-03 10:16 ` [PATCH v11 04/10] arm64/hugetlb: drop the init_mm special case in clear_flush() Wen Jiang
2026-11-03 10:16 ` [PATCH v11 05/10] arm64/vmalloc: allow arch_vmap_pte_range_map_size() to batch multiple CONT_PTE Wen Jiang
2026-11-04 10:18   ` sashiko-bot
2026-11-03 10:16 ` [PATCH v11 06/10] mm/vmalloc: extract vmap_set_ptes() to consolidate PTE mapping logic Wen Jiang
2026-11-03 10:16 ` [PATCH v11 07/10] mm/vmalloc: extend page table walk to support larger page_shift sizes and eliminate page table rewalk Wen Jiang
2026-11-03 10:16 ` [PATCH v11 08/10] mm/vmalloc: extract vm_shift() to consolidate mapping shift selection Wen Jiang
2026-11-03 10:16 ` [PATCH v11 09/10] mm/vmalloc: map contiguous pages in batches for vmap() if possible Wen Jiang
2026-11-04 10:19   ` sashiko-bot
2026-11-03 10:16 ` [PATCH v11 10/10] mm/vmalloc: align vm_area so vmap() can batch mappings Wen Jiang
2026-11-04 10:19   ` sashiko-bot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-197082@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=ajd@linux.ibm.com \
    --cc=akpm@linux-foundation.org \
    --cc=anshuman.khandual@arm.com \
    --cc=baohua@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=chleroy@kernel.org \
    --cc=david@kernel.org \
    --cc=dev.jain@arm.com \
    --cc=jiangwen6@xiaomi.com \
    --cc=jiangwenxiaomi@gmail.com \
    --cc=leo.yan@arm.com \
    --cc=linux-mm@kvack.org \
    --cc=maddy@linux.ibm.com \
    --cc=mpe@ellerman.id.au \
    --cc=npiggin@gmail.com \
    --cc=rppt@kernel.org \
    --cc=ryan.roberts@arm.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=urezki@gmail.com \
    --cc=will@kernel.org \
    --cc=xueyuan.chen21@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox