* [PATCH] x86/mm: don't apply va_align to hugetlb mappings on AMD F15h
@ 2026-08-28 13:57 Laurent Wandrebeck
2026-08-28 17:07 ` Dave Hansen
2026-09-22 8:50 ` [PATCH v2] " Laurent Wandrebeck
0 siblings, 2 replies; 11+ messages in thread
From: Laurent Wandrebeck @ 2026-08-28 13:57 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86
Cc: H. Peter Anvin, Oscar Salvador, Andrew Morton, linux-mm,
linux-kernel, stable
Commit 1317a5e7f7b1 ("arch/x86: teach arch_get_unmapped_area_vmflags to
handle hugetlb mappings") taught get_align_mask() to return
huge_page_mask_align() for a hugetlbfs file, and skipped the pgoff-derived
align_offset for one. It missed the other write to align_offset:
if (filp) {
info.align_mask = get_align_mask(filp);
info.align_offset += get_align_bits();
}
get_align_bits() calls get_align_mask(NULL), so a hugetlbfs file still gets
the F15h I$ anti-aliasing randomization that its own align_mask already
excludes it from. vm_unmapped_area() therefore returns an address
deliberately offset from the huge page boundary, the hugetlb VMA's vm_start
is only PAGE_SIZE aligned, and tearing it down trips
BUG_ON(start & ~huge_page_mask(h)) in __unmap_hugepage_range():
kernel BUG at mm/hugetlb.c:5161!
RIP: 0010:__unmap_hugepage_range+0x64f/0x660
RAX: 000000003fffffff RDX: 00007e9280003000
Call Trace:
__zap_vma_range+0x523/0x680
unmap_vmas+0xa5/0x1a0
exit_mmap+0x13b/0x3f0
do_exit+0x1e4/0x470
That is a 1 GiB mapping on an A10-8770E (family 0x15, model 0x65) running
7.2.0, 0x3000 below a 1 GiB boundary, RAX being ~huge_page_mask(h). Both
hstates crash, and so do both on an FX-8370E (family 0x15, model 0x02)
running 7.1.8, there 0x5000 low. The offset is va_align.bits, drawn once
per boot: identical across hstates within a boot, different between boots
and machines, and a boot that draws zero does not reproduce at any size -
hence the apparent intermittency. The crash is in the teardown path, so the
reservation leaks as well, HugePages_Rsvd owned by nobody until reboot.
Reproduced by mmap()ing MAP_HUGETLB and returning. A Ryzen 5 2500U (family
0x17) on the same 7.2.0 does not reproduce it, as expected since va_align
is only set up for family 0x15. With the patch both hstates return aligned
addresses, and PostgreSQL has mapped a 4 GB hugetlbfs segment for 18.8 h on
2 MiB and 4+ h on 1 GiB pages with no BUG and no leaked reservations.
Fixes: 1317a5e7f7b1 ("arch/x86: teach arch_get_unmapped_area_vmflags to handle hugetlb mappings")
Cc: stable@vger.kernel.org # 6.13+
Signed-off-by: Laurent Wandrebeck <l.wandrebeck@quelquesmots.fr>
---
arch/x86/kernel/sys_x86_64.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 776ae6fa7f2d..6b2be065304f 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -157,7 +157,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len,
}
if (filp) {
info.align_mask = get_align_mask(filp);
- info.align_offset += get_align_bits();
+ if (!is_file_hugepages(filp))
+ info.align_offset += get_align_bits();
}
return vm_unmapped_area(&info);
@@ -222,7 +223,8 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
if (filp) {
info.align_mask = get_align_mask(filp);
- info.align_offset += get_align_bits();
+ if (!is_file_hugepages(filp))
+ info.align_offset += get_align_bits();
}
addr = vm_unmapped_area(&info);
if (!(addr & ~PAGE_MASK))
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH] x86/mm: don't apply va_align to hugetlb mappings on AMD F15h
2026-08-28 13:57 [PATCH] x86/mm: don't apply va_align to hugetlb mappings on AMD F15h Laurent Wandrebeck
@ 2026-08-28 17:07 ` Dave Hansen
2026-08-29 17:47 ` Borislav Petkov
2026-09-22 8:50 ` [PATCH v2] " Laurent Wandrebeck
1 sibling, 1 reply; 11+ messages in thread
From: Dave Hansen @ 2026-08-28 17:07 UTC (permalink / raw)
To: Laurent Wandrebeck, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86
Cc: H. Peter Anvin, Oscar Salvador, Andrew Morton, linux-mm,
linux-kernel, stable
Hey Boris,
These AMD F15h CPUs are, what, 15 years old now? How bad of a
performance hit *was* this issue? Is this optimization worth keeping around?
On 8/28/26 06:57, Laurent Wandrebeck wrote:
> Commit 1317a5e7f7b1 ("arch/x86: teach arch_get_unmapped_area_vmflags to
> handle hugetlb mappings") taught get_align_mask() to return
> huge_page_mask_align() for a hugetlbfs file, and skipped the pgoff-derived
> align_offset for one. It missed the other write to align_offset:
I'm not crazy about this changelog.
> diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
> index 776ae6fa7f2d..6b2be065304f 100644
> --- a/arch/x86/kernel/sys_x86_64.c
> +++ b/arch/x86/kernel/sys_x86_64.c
> @@ -157,7 +157,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len,
> }
> if (filp) {
> info.align_mask = get_align_mask(filp);
> - info.align_offset += get_align_bits();
> + if (!is_file_hugepages(filp))
> + info.align_offset += get_align_bits();
> }
Rather than special-casing hugetlb in two more places, could we just do:
info.align_mask = get_align_mask(filp);
info.align_offset += get_align_bits(filp);
and then pass filp through get_align_bits() to get_align_mask()? I think
that would end up masking the troublesome bits out of va_align.bits.
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH] x86/mm: don't apply va_align to hugetlb mappings on AMD F15h
2026-08-28 17:07 ` Dave Hansen
@ 2026-08-29 17:47 ` Borislav Petkov
[not found] ` <0B48BE2C-2E72-4961-91D9-35E215F537A9@quelquesmots.fr>
0 siblings, 1 reply; 11+ messages in thread
From: Borislav Petkov @ 2026-08-29 17:47 UTC (permalink / raw)
To: Dave Hansen
Cc: Laurent Wandrebeck, Thomas Gleixner, Ingo Molnar, Dave Hansen,
x86, H. Peter Anvin, Oscar Salvador, Andrew Morton, linux-mm,
linux-kernel, stable
On Fri, Aug 28, 2026 at 10:07:42AM -0700, Dave Hansen wrote:
> These AMD F15h CPUs are, what, 15 years old now? How bad of a
> performance hit *was* this issue? Is this optimization worth keeping around?
Oh, look, even back then I did perf measurements:
https://lore.kernel.org/all/1312550110-24160-2-git-send-email-bp@amd64.org/T/#m04c05a9a6f59b73d610b556f1efda8cd9e0487d1
8s penalty for kernel build workload on 3.0.
Do I care about Bulldozer?
Meh, I only have access to a laptop with that uarch and I've been using it
only to test kernels on it so, not really. Besides, we have Zens now which
are soo much better in every aspect so that Bulldozer looks more like a energy
waste than anything else.
But there are apparently folks which still use those and run new kernels on
them so we probably can't axe it off yet...
Looking on the bright side, Laurent can test patches ... :-P
HTH.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2] x86/mm: don't apply va_align to hugetlb mappings on AMD F15h
2026-08-28 13:57 [PATCH] x86/mm: don't apply va_align to hugetlb mappings on AMD F15h Laurent Wandrebeck
2026-08-28 17:07 ` Dave Hansen
@ 2026-09-22 8:50 ` Laurent Wandrebeck
2026-09-28 2:58 ` [tip: x86/urgent] x86/mm: Don't " tip-bot2 for Laurent Wandrebeck
1 sibling, 1 reply; 11+ messages in thread
From: Laurent Wandrebeck @ 2026-09-22 8:50 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86
Cc: H. Peter Anvin, Oscar Salvador, Andrew Morton, linux-mm,
linux-kernel, stable, Dave Hansen
get_align_mask() returns huge_page_mask_align() for hugetlbfs, but
get_align_bits() adds va_align.bits regardless, so vm_unmapped_area()
returns an address off the huge page boundary and
__unmap_hugepage_range() hits BUG_ON(start & ~huge_page_mask(h)) at
teardown.
Pass the file to get_align_bits() and skip the randomisation for
hugetlbfs. Reproduced on Carrizo and FX-8370E, both hstates.
Fixes: 1317a5e7f7b1 ("arch/x86: teach arch_get_unmapped_area_vmflags to handle hugetlb mappings")
Cc: stable@vger.kernel.org # 6.13+
Suggested-by: Dave Hansen <dave.hansen@intel.com>
Signed-off-by: Laurent Wandrebeck <l.wandrebeck@quelquesmots.fr>
---
v2: put the hugetlb case in get_align_bits() instead of guarding both call
sites, per Dave's suggestion to pass filp through. Masking rather than
returning early cannot clear the bits: va_align.mask is an L1I way
size, so it is a subset of huge_page_mask_align().
Re-tested on Carrizo, both hstates.
Link: https://lore.kernel.org/all/20260828135747.724789-1-l.wandrebeck@quelquesmots.fr/
arch/x86/kernel/sys_x86_64.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 776ae6fa7f2d..4c078827f26a 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -50,9 +50,16 @@ static unsigned long get_align_mask(struct file *filp)
* value before calling vm_unmapped_area() or ORed directly to the
* address.
*/
-static unsigned long get_align_bits(void)
+static unsigned long get_align_bits(struct file *filp)
{
- return va_align.bits & get_align_mask(NULL);
+ /*
+ * va_align.bits is smaller than the huge page size and will
+ * lead to misaligned huge pages. Ignore it for huge mappings.
+ */
+ if (is_file_hugepages(filp))
+ return 0;
+
+ return va_align.bits & get_align_mask(filp);
}
static int __init control_va_addr_alignment(char *str)
@@ -157,7 +164,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len,
}
if (filp) {
info.align_mask = get_align_mask(filp);
- info.align_offset += get_align_bits();
+ info.align_offset += get_align_bits(filp);
}
return vm_unmapped_area(&info);
@@ -222,7 +229,7 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
if (filp) {
info.align_mask = get_align_mask(filp);
- info.align_offset += get_align_bits();
+ info.align_offset += get_align_bits(filp);
}
addr = vm_unmapped_area(&info);
if (!(addr & ~PAGE_MASK))
base-commit: 93f51579e7df248780214094418f205253383cc5
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [tip: x86/urgent] x86/mm: Don't apply va_align to hugetlb mappings on AMD F15h
2026-09-22 8:50 ` [PATCH v2] " Laurent Wandrebeck
@ 2026-09-28 2:58 ` tip-bot2 for Laurent Wandrebeck
0 siblings, 0 replies; 11+ messages in thread
From: tip-bot2 for Laurent Wandrebeck @ 2026-09-28 2:58 UTC (permalink / raw)
To: linux-tip-commits
Cc: Dave Hansen, Laurent Wandrebeck, Borislav Petkov (AMD), stable, #,
6.13+,
x86, linux-kernel
The following commit has been merged into the x86/urgent branch of tip:
Commit-ID: d2457a7e2727dc747a61a50d65c2f259afce8c45
Gitweb: https://git.kernel.org/tip/d2457a7e2727dc747a61a50d65c2f259afce8c45
Author: Laurent Wandrebeck <l.wandrebeck@quelquesmots.fr>
AuthorDate: Tue, 22 Sep 2026 10:50:32 +02:00
Committer: Borislav Petkov (AMD) <bp@alien8.de>
CommitterDate: Sun, 27 Sep 2026 19:46:45 -07:00
x86/mm: Don't apply va_align to hugetlb mappings on AMD F15h
get_align_mask() returns huge_page_mask_align() for hugetlbfs, but get_align_bits()
adds va_align.bits regardless, so vm_unmapped_area() returns an address off the huge
page boundary and __unmap_hugepage_range() hits BUG_ON(start & ~huge_page_mask(h)) at
teardown.
This can be triggered on Carrizo and FX-8370E, both hstates.
Pass the file to get_align_bits() and skip the randomisation for hugetlbfs.
[ bp: Massage commit message. ]
Fixes: 1317a5e7f7b1 ("arch/x86: teach arch_get_unmapped_area_vmflags to handle hugetlb mappings")
Suggested-by: Dave Hansen <dave.hansen@intel.com>
Acked-by: Dave Hansen <dave.hansen@intel.com>
Signed-off-by: Laurent Wandrebeck <l.wandrebeck@quelquesmots.fr>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Cc: stable@vger.kernel.org # 6.13+
Link: https://patch.msgid.link/20260922085032.46144-1-l.wandrebeck@quelquesmots.fr
---
arch/x86/kernel/sys_x86_64.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 776ae6f..4c07882 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -50,9 +50,16 @@ static unsigned long get_align_mask(struct file *filp)
* value before calling vm_unmapped_area() or ORed directly to the
* address.
*/
-static unsigned long get_align_bits(void)
+static unsigned long get_align_bits(struct file *filp)
{
- return va_align.bits & get_align_mask(NULL);
+ /*
+ * va_align.bits is smaller than the huge page size and will
+ * lead to misaligned huge pages. Ignore it for huge mappings.
+ */
+ if (is_file_hugepages(filp))
+ return 0;
+
+ return va_align.bits & get_align_mask(filp);
}
static int __init control_va_addr_alignment(char *str)
@@ -157,7 +164,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len,
}
if (filp) {
info.align_mask = get_align_mask(filp);
- info.align_offset += get_align_bits();
+ info.align_offset += get_align_bits(filp);
}
return vm_unmapped_area(&info);
@@ -222,7 +229,7 @@ get_unmapped_area:
if (filp) {
info.align_mask = get_align_mask(filp);
- info.align_offset += get_align_bits();
+ info.align_offset += get_align_bits(filp);
}
addr = vm_unmapped_area(&info);
if (!(addr & ~PAGE_MASK))
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-09-28 2:58 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-28 13:57 [PATCH] x86/mm: don't apply va_align to hugetlb mappings on AMD F15h Laurent Wandrebeck
2026-08-28 17:07 ` Dave Hansen
2026-08-29 17:47 ` Borislav Petkov
[not found] ` <0B48BE2C-2E72-4961-91D9-35E215F537A9@quelquesmots.fr>
2026-08-29 18:51 ` Borislav Petkov
2026-09-01 8:12 ` Laurent Wandrebeck
2026-09-16 20:02 ` Borislav Petkov
2026-09-19 8:47 ` Laurent Wandrebeck
2026-09-19 17:53 ` Borislav Petkov
2026-09-21 16:19 ` Dave Hansen
2026-09-22 8:50 ` [PATCH v2] " Laurent Wandrebeck
2026-09-28 2:58 ` [tip: x86/urgent] x86/mm: Don't " tip-bot2 for Laurent Wandrebeck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®