summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2026-10-13 08:55:37 +0200
committerIngo Molnar <mingo@kernel.org>2026-10-13 08:55:37 +0200
commitec37745bb735edd25ab0306a2065a45cebc2105e (patch)
tree5a6976f4513175eaf908af384cd7a862655a744d
parent01848f8d02777b90cb8f68212c144ac59ddc3beb (diff)
parentd92b5ac5aeba1ffc734576e30a5bca882722de76 (diff)
downloadlinux-next-ec37745bb735edd25ab0306a2065a45cebc2105e.tar.gz
linux-next-ec37745bb735edd25ab0306a2065a45cebc2105e.zip
Merge branch into tip/master: 'x86/mm'
# New commits in x86/mm: d92b5ac5aeba ("x86/mm: Fix spurious warning on __add_pages() failure") 4f8c177caac8 ("x86/mm: Fix void/int conditional in pgd_clear()") ea6fd393cb9e ("x86/mm/pat: Use pr_warn() for early W^X warnings") ebaf7c9bbb1e ("x86/mm/pat: Fix effective RW computation in lookup_address_in_pgd_attr()") Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/include/asm/pgtable.h6
-rw-r--r--arch/x86/mm/init_64.c3
-rw-r--r--arch/x86/mm/pat/set_memory.c23
3 files changed, 26 insertions, 6 deletions
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index d551120a7c88..c79554dac5f7 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -66,7 +66,11 @@ extern pmdval_t early_pmd_flags;
#ifndef __PAGETABLE_P4D_FOLDED
#define set_pgd(pgdp, pgd) native_set_pgd(pgdp, pgd)
-#define pgd_clear(pgd) (pgtable_l5_enabled() ? native_pgd_clear(pgd) : 0)
+#define pgd_clear(pgdp) \
+do { \
+ if (pgtable_l5_enabled()) \
+ native_pgd_clear(pgdp); \
+} while (0)
#endif
#ifndef set_p4d
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 70e682180291..8b6d86fb5a42 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -970,7 +970,8 @@ int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
return -ERANGE;
ret = __add_pages(nid, start_pfn, nr_pages, params);
- WARN_ON_ONCE(ret);
+ if (ret)
+ return ret;
/*
* Special case: add_pages() is called by memremap_pages() for adding device
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 4652487b5572..c71f6774a2f3 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -719,6 +719,21 @@ static inline pgprot_t verify_rwx(pgprot_t old, pgprot_t new, unsigned long star
return new;
end = start + npg * PAGE_SIZE - 1;
+
+ /*
+ * If the kernel text is still RWX, gently complain, this could be a
+ * false positive.
+ * Once debug_checkwx() becomes mandatory for CONFIG_STRICT_KERNEL_RWX,
+ * the warning can be removed completely.
+ */
+ if (!kernel_set_to_readonly) {
+ pr_warn_once("CPA detected W^X violation: %016llx -> %016llx range: 0x%016lx - 0x%016lx PFN %lx\n",
+ (unsigned long long)pgprot_val(old),
+ (unsigned long long)pgprot_val(new),
+ start, end, pfn);
+ return new;
+ }
+
WARN_ONCE(1, "CPA detected W^X violation: %016llx -> %016llx range: 0x%016lx - 0x%016lx PFN %lx\n",
(unsigned long long)pgprot_val(old),
(unsigned long long)pgprot_val(new),
@@ -754,7 +769,7 @@ pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address,
*level = PG_LEVEL_512G;
*nx |= pgd_flags(*pgd) & _PAGE_NX;
- *rw &= pgd_flags(*pgd) & _PAGE_RW;
+ *rw &= !!(pgd_flags(*pgd) & _PAGE_RW);
p4d = p4d_offset(pgd, address);
if (p4d_none(*p4d))
@@ -765,7 +780,7 @@ pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address,
*level = PG_LEVEL_1G;
*nx |= p4d_flags(*p4d) & _PAGE_NX;
- *rw &= p4d_flags(*p4d) & _PAGE_RW;
+ *rw &= !!(p4d_flags(*p4d) & _PAGE_RW);
pud = pud_offset(p4d, address);
if (pud_none(*pud))
@@ -776,7 +791,7 @@ pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address,
*level = PG_LEVEL_2M;
*nx |= pud_flags(*pud) & _PAGE_NX;
- *rw &= pud_flags(*pud) & _PAGE_RW;
+ *rw &= !!(pud_flags(*pud) & _PAGE_RW);
pmd = pmd_offset(pud, address);
if (pmd_none(*pmd))
@@ -787,7 +802,7 @@ pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address,
*level = PG_LEVEL_4K;
*nx |= pmd_flags(*pmd) & _PAGE_NX;
- *rw &= pmd_flags(*pmd) & _PAGE_RW;
+ *rw &= !!(pmd_flags(*pmd) & _PAGE_RW);
return pte_offset_kernel(pmd, address);
}