* [PATCH] ARM: mm: align hugetlb mappings to the huge page size
@ 2026-09-01 8:57 Karl Mehltretter
0 siblings, 0 replies; only message in thread
From: Karl Mehltretter @ 2026-09-01 8:57 UTC (permalink / raw)
To: Russell King, linux-arm-kernel
Cc: Karl Mehltretter, Oscar Salvador, Andrew Morton, Muchun Song,
David Hildenbrand, linux-mm, linux-kernel
mmap(MAP_HUGETLB) on 32-bit Arm can return an address which is not
aligned to the huge page size. In a QEMU virt guest, unmapping the VMA
then hits the alignment check in __unmap_hugepage_range():
kernel BUG at mm/hugetlb.c:5213!
Internal error: Oops - BUG: 0 [#1] SMP ARM
PC is at __unmap_hugepage_range+0x540/0x584
LR is at __zap_vma_range+0x13a0/0x1410
Commit 7bd3f1e1a9ae ("mm: make hugetlb mappings go through
mm_get_unmapped_area_vmflags") made hugetlb mappings use the
architecture's arch_get_unmapped_area(). The generic implementations
handle hugetlb alignment, but the Arm implementations only account for
the optional SHMLBA cache-colouring constraint. A 4 KiB-page kernel can
therefore align the mapping to 4 KiB or 16 KiB instead of the required
2 MiB.
Set the alignment mask from the file's hstate for hugetlb mappings in
both Arm implementations. Huge-page alignment also satisfies the
SHMLBA constraint.
Fixes: 7bd3f1e1a9ae ("mm: make hugetlb mappings go through mm_get_unmapped_area_vmflags")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
Tested an LPAE multi_v7_defconfig kernel on QEMU virt with
-cpu max,aarch64=off and -cpu cortex-a15, using both the default and
legacy VA layouts. The LTP hugemmap01/04/05/06, hugefork01/02,
hugeshmat01, hugeshmget01, and hugefallocate01 tests gave 16 TPASS and
no failures on either CPU model.
Also tested on a Raspberry Pi 400. The unpatched kernel returned a
misaligned address and became unresponsive while touching the mapping.
The patched kernel returned an aligned address, touched the full mapping,
and unmapped it cleanly.
arch/arm/mm/mmap.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 3dbb383c26d54..dbb3f07a77852 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -11,6 +11,7 @@
#include <linux/io.h>
#include <linux/personality.h>
#include <linux/random.h>
+#include <linux/hugetlb.h>
#include <asm/cachetype.h>
#define COLOUR_ALIGN(addr,pgoff) \
@@ -72,7 +73,10 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.length = len;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
- info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ if (filp && is_file_hugepages(filp))
+ info.align_mask = huge_page_mask_align(filp);
+ else
+ info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
return vm_unmapped_area(&info);
}
@@ -123,7 +127,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.length = len;
info.low_limit = FIRST_USER_ADDRESS;
info.high_limit = mm->mmap_base;
- info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ if (filp && is_file_hugepages(filp))
+ info.align_mask = huge_page_mask_align(filp);
+ else
+ info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
base-commit: abdf623ddb75b24659018d3952d8f61937306ae5
--
2.53.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-01 8:58 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-01 8:57 [PATCH] ARM: mm: align hugetlb mappings to the huge page size Karl Mehltretter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox