diff options
| author | Mark Brown <broonie@kernel.org> | 2026-07-27 13:25:11 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-07-27 13:25:11 +0100 |
| commit | fed738703be77b2ff979335d0a8dab4efb59bc64 (patch) | |
| tree | c107a9507433e06ffc231a847cdf3e6ce1b09fec /arch | |
| parent | 1432683838d9122c62bf4a0fa139fcf26968911e (diff) | |
| parent | 5bff6e212ff5715e86f51c6038ec5b1548f0d8a3 (diff) | |
| download | linux-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.h | 4 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/xive/common.c | 4 | ||||
| -rw-r--r-- | arch/riscv/include/asm/cacheflush.h | 15 | ||||
| -rw-r--r-- | arch/riscv/include/asm/pgtable.h | 9 | ||||
| -rw-r--r-- | arch/riscv/kernel/entry.S | 11 |
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 |
