summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-10-04 08:59:22 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-10-04 08:59:22 -0700
commit06ac073129191a01d77933ed381f89c67674db6f (patch)
tree6e3af9ede358aa55a108c39f519635b8882c243a /arch
parent942e4a0e46bfd0efd3f87f70bf186c54aaaeb138 (diff)
parenta661c34fe693c8f9ef29b45ee71cfa1fe593502b (diff)
downloadlinux-stable-06ac073129191a01d77933ed381f89c67674db6f.tar.gz
linux-stable-06ac073129191a01d77933ed381f89c67674db6f.zip
Merge tag 'x86-urgent-2026-10-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar: - Don't apply va_align to hugetlb mappings on AMD F15h systems that have custom va_align.bits values (Laurent Wandrebeck) - Fix PMD teardown handling regression flagged by lockdep (Mikhail Gavrilov) - Hide ptrace header register offset macros behind __ASSEMBLER__ or __FRAME_OFFSETS, to fix user-space build errors that may trigger if they happen to shadow these short and generic macro names (Nick Desaulniers) * tag 'x86-urgent-2026-10-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: {x86,um}/uapi/ptrace: Guard register offset macros with __ASSEMBLER__ or __FRAME_OFFSETS x86/mm: Drop unnecessary PMD page copy when freeing x86/mm: Don't apply va_align to hugetlb mappings on AMD F15h
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/uapi/asm/ptrace-abi.h4
-rw-r--r--arch/x86/kernel/sys_x86_64.c15
-rw-r--r--arch/x86/mm/pgtable.c38
-rw-r--r--arch/x86/um/asm/ptrace.h4
-rw-r--r--arch/x86/um/ptrace_32.c1
5 files changed, 29 insertions, 33 deletions
diff --git a/arch/x86/include/uapi/asm/ptrace-abi.h b/arch/x86/include/uapi/asm/ptrace-abi.h
index 5823584de..3656955c6 100644
--- a/arch/x86/include/uapi/asm/ptrace-abi.h
+++ b/arch/x86/include/uapi/asm/ptrace-abi.h
@@ -2,6 +2,7 @@
#ifndef _ASM_X86_PTRACE_ABI_H
#define _ASM_X86_PTRACE_ABI_H
+#if defined(__ASSEMBLER__) || defined(__FRAME_OFFSETS)
#ifdef __i386__
#define EBX 0
@@ -25,7 +26,6 @@
#else /* __i386__ */
-#if defined(__ASSEMBLER__) || defined(__FRAME_OFFSETS)
/*
* C ABI says these regs are callee-preserved. They aren't saved on kernel entry
* unless syscall needs a complete, fully filled "struct pt_regs".
@@ -57,12 +57,12 @@
#define EFLAGS 144
#define RSP 152
#define SS 160
-#endif /* __ASSEMBLER__ */
/* top of stack page */
#define FRAME_SIZE 168
#endif /* !__i386__ */
+#endif /* defined(__ASSEMBLER__) || defined(__FRAME_OFFSETS) */
/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
#define PTRACE_GETREGS 12
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 776ae6fa7..4c078827f 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))
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index cb03f5a2b..4a105f283 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -705,47 +705,37 @@ int pmd_clear_huge(pmd_t *pmd)
}
#ifdef CONFIG_X86_64
-/**
- * pud_free_pmd_page - Clear PUD entry and free PMD page
- * @pud: Pointer to a PUD
- * @addr: Virtual address associated with PUD
- *
- * Context: The PUD range has been unmapped and TLB purged.
- * Return: 1 if clearing the entry succeeded. 0 otherwise.
- *
- * NOTE: Callers must allow a single page allocation.
+/*
+ * Given a PUD poitner, detach and free the pointed-to
+ * PMD page and any PTE page children. The entire range
+ * under the PUD must not have any valid translations
+ * and the TLB must have already been flushed.
*/
int pud_free_pmd_page(pud_t *pud, unsigned long addr)
{
- pmd_t *pmd, *pmd_sv;
struct ptdesc *pt;
+ pmd_t *pmd;
int i;
pmd = pud_pgtable(*pud);
- pmd_sv = (pmd_t *)__get_free_page(GFP_KERNEL);
- if (!pmd_sv)
- return 0;
-
- for (i = 0; i < PTRS_PER_PMD; i++) {
- pmd_sv[i] = pmd[i];
- if (!pmd_none(pmd[i]))
- pmd_clear(&pmd[i]);
- }
+ /* Detach the PMD page: */
pud_clear(pud);
- /* INVLPG to clear all paging-structure caches */
+ /*
+ * PMD and all its descendents are unreachable
+ * via normal page walks. Make them unreachable
+ * in cached mid-level walks too:
+ */
flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1);
for (i = 0; i < PTRS_PER_PMD; i++) {
- if (!pmd_none(pmd_sv[i])) {
- pt = page_ptdesc(pmd_page(pmd_sv[i]));
+ if (!pmd_none(pmd[i])) {
+ pt = page_ptdesc(pmd_page(pmd[i]));
pagetable_dtor_free(pt);
}
}
- free_page((unsigned long)pmd_sv);
-
pmd_free(&init_mm, pmd);
return 1;
diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h
index 2641d28d1..439c4151f 100644
--- a/arch/x86/um/asm/ptrace.h
+++ b/arch/x86/um/asm/ptrace.h
@@ -13,9 +13,7 @@ enum {
};
#include <linux/compiler.h>
-#ifndef CONFIG_X86_32
-#define __FRAME_OFFSETS /* Needed to get the R* macros */
-#endif
+#define __FRAME_OFFSETS /* Needed to get the register macros */
#include <asm/ptrace-generic.h>
#define user_mode(r) UPT_IS_USER(&(r)->regs)
diff --git a/arch/x86/um/ptrace_32.c b/arch/x86/um/ptrace_32.c
index 3af3cb821..9e9155b0e 100644
--- a/arch/x86/um/ptrace_32.c
+++ b/arch/x86/um/ptrace_32.c
@@ -7,6 +7,7 @@
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/regset.h>
+#define __FRAME_OFFSETS
#include <asm/ptrace-abi.h>
#include <registers.h>
#include <skas.h>