summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-07-27 13:25:11 +0100
committerMark Brown <broonie@kernel.org>2026-07-27 13:25:11 +0100
commitfed738703be77b2ff979335d0a8dab4efb59bc64 (patch)
treec107a9507433e06ffc231a847cdf3e6ce1b09fec /arch
parent1432683838d9122c62bf4a0fa139fcf26968911e (diff)
parent5bff6e212ff5715e86f51c6038ec5b1548f0d8a3 (diff)
downloadlinux-next-fed738703be77b2ff979335d0a8dab4efb59bc64.tar.gz
linux-next-fed738703be77b2ff979335d0a8dab4efb59bc64.zip
Merge branch 'mm-nonmm-unstable' of https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/xive.h4
-rw-r--r--arch/powerpc/sysdev/xive/common.c4
-rw-r--r--arch/riscv/include/asm/cacheflush.h15
-rw-r--r--arch/riscv/include/asm/pgtable.h9
-rw-r--r--arch/riscv/kernel/entry.S11
5 files changed, 31 insertions, 12 deletions
diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h
index efb0f5effcc6..4e3e3358993c 100644
--- a/arch/powerpc/include/asm/xive.h
+++ b/arch/powerpc/include/asm/xive.h
@@ -91,7 +91,7 @@ static inline bool xive_enabled(void) { return __xive_enabled; }
bool xive_spapr_init(void);
bool xive_native_init(void);
-void xive_smp_probe(void);
+int xive_smp_probe(void);
int xive_smp_prepare_cpu(unsigned int cpu);
void xive_smp_setup_cpu(void);
void xive_smp_disable_cpu(void);
@@ -153,7 +153,7 @@ static inline bool xive_enabled(void) { return false; }
static inline bool xive_spapr_init(void) { return false; }
static inline bool xive_native_init(void) { return false; }
-static inline void xive_smp_probe(void) { }
+static inline int xive_smp_probe(void) { return -EINVAL; }
static inline int xive_smp_prepare_cpu(unsigned int cpu) { return -EINVAL; }
static inline void xive_smp_setup_cpu(void) { }
static inline void xive_smp_disable_cpu(void) { }
diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c
index dadd1f46ec93..2e315ef1e75d 100644
--- a/arch/powerpc/sysdev/xive/common.c
+++ b/arch/powerpc/sysdev/xive/common.c
@@ -1257,7 +1257,7 @@ noinstr static void xive_cleanup_cpu_ipi(unsigned int cpu, struct xive_cpu *xc)
xive_ops->put_ipi(cpu, xc);
}
-void __init xive_smp_probe(void)
+int __init xive_smp_probe(void)
{
smp_ops->cause_ipi = xive_cause_ipi;
@@ -1266,6 +1266,8 @@ void __init xive_smp_probe(void)
/* Allocate and setup IPI for the boot CPU */
xive_setup_cpu_ipi(smp_processor_id());
+
+ return 0;
}
#endif /* CONFIG_SMP */
diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
index c2b0a2928f06..c6297a1d2645 100644
--- a/arch/riscv/include/asm/cacheflush.h
+++ b/arch/riscv/include/asm/cacheflush.h
@@ -6,7 +6,9 @@
#ifndef _ASM_RISCV_CACHEFLUSH_H
#define _ASM_RISCV_CACHEFLUSH_H
+#include <linux/array_size.h>
#include <linux/mm.h>
+#include <asm/barrier.h>
static inline void local_flush_icache_all(void)
{
@@ -47,11 +49,22 @@ extern char _end[];
static inline void mark_new_valid_map(void)
{
/*
+ * Orders any previous page table writes before setting bits in
+ * new_valid_map_cpus. Pairs with the sfence.vma in
+ * new_valid_map_cpus_check.
+ */
+ smp_wmb();
+
+ /*
* We don't care if concurrently a cpu resets this value since
* the only place this can happen is in handle_exception() where
* an sfence.vma is emitted.
+ *
+ * Not memset() or bitmap_fill() to avoid any possible compiler
+ * shenanigans.
*/
- bitmap_fill(new_valid_map_cpus, NR_CPUS);
+ for (size_t i = 0; i < ARRAY_SIZE(new_valid_map_cpus); i++)
+ WRITE_ONCE(new_valid_map_cpus[i], -1UL);
}
#define flush_cache_vmap flush_cache_vmap
static inline void flush_cache_vmap(unsigned long start, unsigned long end)
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 7f21742b2b6a..1225cf05696a 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -983,7 +983,14 @@ static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long
static inline bool pmd_user_accessible_page(struct mm_struct *mm, unsigned long addr, pmd_t pmd)
{
- return pmd_leaf(pmd) && pmd_user(pmd);
+ /*
+ * page_table_check() must ignore THP split invalidation entries created by
+ * pmd_mkinvalid(). These retain _PAGE_LEAF so pmd_present()/pmd_leaf() stay
+ * true during the split, but they no longer describe a user-accessible
+ * mapping once both _PAGE_PRESENT and _PAGE_PROT_NONE are cleared.
+ */
+ return (pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROT_NONE)) &&
+ (pmd_val(pmd) & _PAGE_LEAF) && pmd_user(pmd);
}
static inline bool pud_user_accessible_page(struct mm_struct *mm, unsigned long addr, pud_t pud)
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index d799c4e56f80..4bb78dff1f38 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -76,6 +76,8 @@
amoxor.d a0, a1, (a0)
/*
+ * Pairs with the smp_wmb() in mark_new_valid_map()
+ *
* A sfence.vma is required here. Even if we had Svvptc, there's no
* guarantee that after returning we wouldn't just fault again.
*/
@@ -141,13 +143,8 @@ SYM_CODE_START(handle_exception)
/*
* The RISC-V kernel does not flush TLBs on all CPUS after each new
* vmalloc mapping or kfence_unprotect(), which may result in
- * exceptions:
- *
- * - if the uarch caches invalid entries, the new mapping would not be
- * observed by the page table walker and an invalidation is needed.
- * - if the uarch does not cache invalid entries, a reordered access
- * could "miss" the new mapping and traps: in that case, we only need
- * to retry the access, no sfence.vma is required.
+ * exceptions. In that case, we need to sfence.vma to "receive" the new
+ * mappings and retry, whether or not we have Svvptc.
*/
new_valid_map_cpus_check
#endif