Re: [PATCH v14 7/9] powerpc: Set ARCH_HAS_STRICT_MODULE_RWX
Le 17/05/2021 à 05:28, Jordan Niethe a écrit : From: Russell Currey To enable strict module RWX on powerpc, set: CONFIG_STRICT_MODULE_RWX=y You should also have CONFIG_STRICT_KERNEL_RWX=y set to have any real security benefit. ARCH_HAS_STRICT_MODULE_RWX is set to require ARCH_HAS_STRICT_KERNEL_RWX. This is due to a quirk in arch/Kconfig and arch/powerpc/Kconfig that makes STRICT_MODULE_RWX *on by default* in configurations where STRICT_KERNEL_RWX is *unavailable*. Since this doesn't make much sense, and module RWX without kernel RWX doesn't make much sense, having the same dependencies as kernel RWX works around this problem. Book32s/32 processors with a hash mmu (i.e. 604 core) can not set memory ^^ Book32s ==> Book3s protection on a page by page basis so do not enable. It is not exactly that. The problem on 604 is for _exec_ protection. Note that on book3s/32, on both 603 and 604 core, it is not possible to write protect kernel pages. So maybe it would make sense to disable ARCH_HAS_STRICT_MODULE_RWX on CONFIG_PPC_BOOK3S_32 completely, I'm not sure. Signed-off-by: Russell Currey [jpn: - predicate on !PPC_BOOK3S_604 - make module_alloc() use PAGE_KERNEL protection] Signed-off-by: Jordan Niethe Reviewed-by: Christophe Leroy --- v10: - Predicate on !PPC_BOOK3S_604 - Make module_alloc() use PAGE_KERNEL protection v11: - Neaten up v13: Use strict_kernel_rwx_enabled() v14: Make changes to module_alloc() its own commit --- arch/powerpc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index cce0a137b046..cb5d9d862c35 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -140,6 +140,7 @@ config PPC select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64 select ARCH_HAS_SET_MEMORY select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !HIBERNATION) + select ARCH_HAS_STRICT_MODULE_RWX if ARCH_HAS_STRICT_KERNEL_RWX && !PPC_BOOK3S_604 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UACCESS_FLUSHCACHE select ARCH_HAS_COPY_MC if PPC64
Re: [PATCH v14 3/9] powerpc/modules: Make module_alloc() Strict Module RWX aware
On Mon, May 17, 2021 at 4:37 PM Christophe Leroy wrote: > > > > Le 17/05/2021 à 05:28, Jordan Niethe a écrit : > > Make module_alloc() use PAGE_KERNEL protections instead of > > PAGE_KERNEL_EXEX if Strict Module RWX is enabled. > > > > Signed-off-by: Jordan Niethe > > --- > > v14: - Split out from powerpc: Set ARCH_HAS_STRICT_MODULE_RWX > > - Add and use strict_module_rwx_enabled() helper > > --- > > arch/powerpc/include/asm/mmu.h | 5 + > > arch/powerpc/kernel/module.c | 4 +++- > > 2 files changed, 8 insertions(+), 1 deletion(-) > > > > diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h > > index 607168b1aef4..7710bf0cbf8a 100644 > > --- a/arch/powerpc/include/asm/mmu.h > > +++ b/arch/powerpc/include/asm/mmu.h > > @@ -357,6 +357,11 @@ static inline bool strict_kernel_rwx_enabled(void) > > return false; > > } > > #endif > > + > > +static inline bool strict_module_rwx_enabled(void) > > +{ > > + return IS_ENABLED(CONFIG_STRICT_MODULE_RWX) && > > strict_kernel_rwx_enabled(); > > +} > > Looking at arch/Kconfig, I have the feeling that it is possible to select > CONFIG_STRICT_MODULE_RWX > without selecting CONFIG_STRICT_KERNEL_RWX. > > In that case, strict_kernel_rwx_enabled() will return false. Ok, if someone did that currently it would break things, e.g. code patching. I think it should it be made impossible to CONFIG_STRICT_MODULE_RWX without CONFIG_STRICT_KERNEL_RWX? > > > #endif /* !__ASSEMBLY__ */ > > > > /* The kernel use the constants below to index in the page sizes array. > > diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c > > index 3f35c8d20be7..ed04a3ba66fe 100644 > > --- a/arch/powerpc/kernel/module.c > > +++ b/arch/powerpc/kernel/module.c > > @@ -92,12 +92,14 @@ int module_finalize(const Elf_Ehdr *hdr, > > static __always_inline void * > > __module_alloc(unsigned long size, unsigned long start, unsigned long end) > > { > > + pgprot_t prot = strict_module_rwx_enabled() ? PAGE_KERNEL : > > PAGE_KERNEL_EXEC; > > + > > /* > >* Don't do huge page allocations for modules yet until more testing > >* is done. STRICT_MODULE_RWX may require extra work to support this > >* too. > >*/ > > - return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, > > PAGE_KERNEL_EXEC, > > + return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, prot, > > VM_FLUSH_RESET_PERMS | VM_NO_HUGE_VMAP, > > NUMA_NO_NODE, > > __builtin_return_address(0)); > > } > >
Re: [RFC 1/4] drivers/nvdimm: Add perf interface to expose nvdimm performance stats
On 5/14/21 5:17 PM, Peter Zijlstra wrote: > On Thu, May 13, 2021 at 05:56:14PM +0530, kajoljain wrote: > >> But yes the current read/add/del functions are not adding value. We >> could add an arch/platform specific function which could handle the >> capturing of the counter data and do the rest of the operation here, >> is this approach better? > > Right; have your register_nvdimm_pmu() set pmu->{add,del,read} to > nd_pmu->{add,del,read} directly, don't bother with these intermediates. > Also you can WARN_ON_ONCE() if any of them are NULL and fail > registration at that point. > Hi Peter, I will make all required changes and send next version of this patchset soon. Thanks, Kajol Jain
Re: [PATCH v14 6/9] powerpc/bpf: Write protect JIT code
Le 17/05/2021 à 05:28, Jordan Niethe a écrit : Add the necessary call to bpf_jit_binary_lock_ro() to remove write and add exec permissions to the JIT image after it has finished being written. Without CONFIG_STRICT_MODULE_RWX the image will be writable and executable until the call to bpf_jit_binary_lock_ro(). And _with_ CONFIG_STRICT_MODULE_RWX what will happen ? It will be _writable_ but not _executable_ ? Reviewed-by: Christophe Leroy Signed-off-by: Jordan Niethe --- v10: New to series v11: Remove CONFIG_STRICT_MODULE_RWX conditional --- arch/powerpc/net/bpf_jit_comp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 6c8c268e4fe8..53aefee3fe70 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -237,6 +237,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) fp->jited_len = alloclen; bpf_flush_icache(bpf_hdr, (u8 *)bpf_hdr + (bpf_hdr->pages * PAGE_SIZE)); + bpf_jit_binary_lock_ro(bpf_hdr); if (!fp->is_func || extra_pass) { bpf_prog_fill_jited_linfo(fp, addrs); out_addrs:
Re: [PATCH v14 3/9] powerpc/modules: Make module_alloc() Strict Module RWX aware
Le 17/05/2021 à 05:28, Jordan Niethe a écrit : Make module_alloc() use PAGE_KERNEL protections instead of PAGE_KERNEL_EXEX if Strict Module RWX is enabled. Signed-off-by: Jordan Niethe --- v14: - Split out from powerpc: Set ARCH_HAS_STRICT_MODULE_RWX - Add and use strict_module_rwx_enabled() helper --- arch/powerpc/include/asm/mmu.h | 5 + arch/powerpc/kernel/module.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 607168b1aef4..7710bf0cbf8a 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -357,6 +357,11 @@ static inline bool strict_kernel_rwx_enabled(void) return false; } #endif + +static inline bool strict_module_rwx_enabled(void) +{ + return IS_ENABLED(CONFIG_STRICT_MODULE_RWX) && strict_kernel_rwx_enabled(); +} Looking at arch/Kconfig, I have the feeling that it is possible to select CONFIG_STRICT_MODULE_RWX without selecting CONFIG_STRICT_KERNEL_RWX. In that case, strict_kernel_rwx_enabled() will return false. #endif /* !__ASSEMBLY__ */ /* The kernel use the constants below to index in the page sizes array. diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index 3f35c8d20be7..ed04a3ba66fe 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c @@ -92,12 +92,14 @@ int module_finalize(const Elf_Ehdr *hdr, static __always_inline void * __module_alloc(unsigned long size, unsigned long start, unsigned long end) { + pgprot_t prot = strict_module_rwx_enabled() ? PAGE_KERNEL : PAGE_KERNEL_EXEC; + /* * Don't do huge page allocations for modules yet until more testing * is done. STRICT_MODULE_RWX may require extra work to support this * too. */ - return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, PAGE_KERNEL_EXEC, + return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, prot, VM_FLUSH_RESET_PERMS | VM_NO_HUGE_VMAP, NUMA_NO_NODE, __builtin_return_address(0)); }
[Bug 213069] kernel BUG at arch/powerpc/include/asm/book3s/64/hash-4k.h:147! Oops: Exception in kernel mode, sig: 5 [#1]
https://bugzilla.kernel.org/show_bug.cgi?id=213069 Christophe Leroy (christophe.le...@csgroup.eu) changed: What|Removed |Added CC||christophe.le...@csgroup.eu --- Comment #2 from Christophe Leroy (christophe.le...@csgroup.eu) --- The bug is not in powerpc but in function pmd_basic_tests() in mm/debug_vm_pgtable.c (https://elixir.bootlin.com/linux/v5.13-rc1/source/mm/debug_vm_pgtable.c#L146) pfn_pmd() should not be called before the has_transparent_hugepage() verification. Same problem in pmd_advanced_tests() And there is the exact same issue with PUD tests with pfn_pud() function. -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
[PATCH 4/4] powerpc: Enable KFENCE on BOOK3S/64
From: Christophe Leroy This reuses the DEBUG_PAGEALLOC logic. Tested with CONFIG_KFENCE + CONFIG_KUNIT + CONFIG_KFENCE_KUNIT_TEST on radix and hash. Signed-off-by: Christophe Leroy [jpn: Handle radix] Signed-off-by: Jordan Niethe --- arch/powerpc/Kconfig | 2 +- arch/powerpc/include/asm/book3s/64/pgtable.h | 2 +- arch/powerpc/include/asm/kfence.h| 19 +++ arch/powerpc/mm/book3s64/hash_utils.c| 12 ++-- arch/powerpc/mm/book3s64/radix_pgtable.c | 8 +--- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 6df64d6815df..1743364d7370 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -196,7 +196,7 @@ config PPC select HAVE_ARCH_KASAN if PPC32 && PPC_PAGE_SHIFT <= 14 select HAVE_ARCH_KASAN_VMALLOC if PPC32 && PPC_PAGE_SHIFT <= 14 select HAVE_ARCH_KGDB - select HAVE_ARCH_KFENCE if PPC32 + select HAVE_ARCH_KFENCE if ARCH_SUPPORTS_DEBUG_PAGEALLOC select HAVE_ARCH_MMAP_RND_BITS select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT select HAVE_ARCH_NVRAM_OPS diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index b89482aed82a..35300f2ee5d0 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -822,7 +822,7 @@ static inline bool check_pte_access(unsigned long access, unsigned long ptev) * Generic functions with hash/radix callbacks */ -#ifdef CONFIG_DEBUG_PAGEALLOC +#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE) static inline void __kernel_map_pages(struct page *page, int numpages, int enable) { if (radix_enabled()) diff --git a/arch/powerpc/include/asm/kfence.h b/arch/powerpc/include/asm/kfence.h index a9846b68c6b9..9d388df7c1a8 100644 --- a/arch/powerpc/include/asm/kfence.h +++ b/arch/powerpc/include/asm/kfence.h @@ -11,11 +11,29 @@ #include #include +#if defined(CONFIG_PPC64) && !defined(PPC64_ELF_ABI_v2) +#define ARCH_FUNC_PREFIX "." +#endif + static inline bool arch_kfence_init_pool(void) { return true; } +#ifdef CONFIG_PPC64 +static inline bool kfence_protect_page(unsigned long addr, bool protect) +{ + struct page *page; + + page = virt_to_page(addr); + if (protect) + __kernel_map_pages(page, 1, 0); + else + __kernel_map_pages(page, 1, 1); + + return true; +} +#else static inline bool kfence_protect_page(unsigned long addr, bool protect) { pte_t *kpte = virt_to_kpte(addr); @@ -29,5 +47,6 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect) return true; } +#endif #endif /* __ASM_POWERPC_KFENCE_H */ diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c index fe5cf1cf4dd5..fecb379426e7 100644 --- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -323,8 +323,8 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, break; cond_resched(); - if (debug_pagealloc_enabled() && - (paddr >> PAGE_SHIFT) < linear_map_hash_count) + if (debug_pagealloc_enabled_or_kfence() && + (paddr >> PAGE_SHIFT) < linear_map_hash_count) linear_map_hash_slots[paddr >> PAGE_SHIFT] = ret | 0x80; } return ret < 0 ? ret : 0; @@ -672,7 +672,7 @@ static void __init htab_init_page_sizes(void) bool aligned = true; init_hpte_page_sizes(); - if (!debug_pagealloc_enabled()) { + if (!debug_pagealloc_enabled_or_kfence()) { /* * Pick a size for the linear mapping. Currently, we only * support 16M, 1M and 4K which is the default @@ -960,7 +960,7 @@ static void __init htab_initialize(void) prot = pgprot_val(PAGE_KERNEL); - if (debug_pagealloc_enabled()) { + if (debug_pagealloc_enabled_or_kfence()) { linear_map_hash_count = memblock_end_of_DRAM() >> PAGE_SHIFT; linear_map_hash_slots = memblock_alloc_try_nid( linear_map_hash_count, 1, MEMBLOCK_LOW_LIMIT, @@ -1936,7 +1936,7 @@ long hpte_insert_repeating(unsigned long hash, unsigned long vpn, return slot; } -#ifdef CONFIG_DEBUG_PAGEALLOC +#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE) static DEFINE_SPINLOCK(linear_map_hash_lock); static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) @@ -2009,7 +2009,7 @@ void hash__kernel_map_pages(struct page *page, int numpages, int enable) } local_irq_restore(flags); } -#endif /* CONFIG_DEBUG_PAGEALLOC */ +#endif /* CONFIG_DEBUG_PAGEALLOC || CONFIG_KFENCE */ void ha
[PATCH 3/4] powerpc/64s: Allow double call of kernel_[un]map_linear_page()
From: Christophe Leroy If the page is already mapped resp. already unmapped, bail out. Signed-off-by: Christophe Leroy Signed-off-by: Jordan Niethe --- arch/powerpc/mm/book3s64/hash_utils.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c index d74482cce064..fe5cf1cf4dd5 100644 --- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -1953,6 +1953,9 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) if (!vsid) return; + if (linear_map_hash_slots[lmi] & 0x80) + return; + ret = hpte_insert_repeating(hash, vpn, __pa(vaddr), mode, HPTE_V_BOLTED, mmu_linear_psize, mmu_kernel_ssize); @@ -1972,7 +1975,10 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi) hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize); spin_lock(&linear_map_hash_lock); - BUG_ON(!(linear_map_hash_slots[lmi] & 0x80)); + if (!(linear_map_hash_slots[lmi] & 0x80)) { + spin_unlock(&linear_map_hash_lock); + return; + } hidx = linear_map_hash_slots[lmi] & 0x7f; linear_map_hash_slots[lmi] = 0; spin_unlock(&linear_map_hash_lock); -- 2.25.1
[PATCH 2/4] powerpc/64s: Remove unneeded #ifdef CONFIG_DEBUG_PAGEALLOC in hash_utils
From: Christophe Leroy debug_pagealloc_enabled() is always defined and constant folds to 'false' when CONFIG_DEBUG_PAGEALLOC is not enabled. Remove the #ifdefs, the code and associated static variables will be optimised out by the compiler when CONFIG_DEBUG_PAGEALLOC is not defined. Signed-off-by: Christophe Leroy Signed-off-by: Jordan Niethe --- arch/powerpc/mm/book3s64/hash_utils.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c index 5b9709075fbd..d74482cce064 100644 --- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -126,11 +126,8 @@ EXPORT_SYMBOL_GPL(mmu_slb_size); #ifdef CONFIG_PPC_64K_PAGES int mmu_ci_restrictions; #endif -#ifdef CONFIG_DEBUG_PAGEALLOC static u8 *linear_map_hash_slots; static unsigned long linear_map_hash_count; -static DEFINE_SPINLOCK(linear_map_hash_lock); -#endif /* CONFIG_DEBUG_PAGEALLOC */ struct mmu_hash_ops mmu_hash_ops; EXPORT_SYMBOL(mmu_hash_ops); @@ -326,11 +323,9 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, break; cond_resched(); -#ifdef CONFIG_DEBUG_PAGEALLOC if (debug_pagealloc_enabled() && (paddr >> PAGE_SHIFT) < linear_map_hash_count) linear_map_hash_slots[paddr >> PAGE_SHIFT] = ret | 0x80; -#endif /* CONFIG_DEBUG_PAGEALLOC */ } return ret < 0 ? ret : 0; } @@ -965,7 +960,6 @@ static void __init htab_initialize(void) prot = pgprot_val(PAGE_KERNEL); -#ifdef CONFIG_DEBUG_PAGEALLOC if (debug_pagealloc_enabled()) { linear_map_hash_count = memblock_end_of_DRAM() >> PAGE_SHIFT; linear_map_hash_slots = memblock_alloc_try_nid( @@ -975,7 +969,6 @@ static void __init htab_initialize(void) panic("%s: Failed to allocate %lu bytes max_addr=%pa\n", __func__, linear_map_hash_count, &ppc64_rma_size); } -#endif /* CONFIG_DEBUG_PAGEALLOC */ /* create bolted the linear mapping in the hash table */ for_each_mem_range(i, &base, &end) { @@ -1944,6 +1937,8 @@ long hpte_insert_repeating(unsigned long hash, unsigned long vpn, } #ifdef CONFIG_DEBUG_PAGEALLOC +static DEFINE_SPINLOCK(linear_map_hash_lock); + static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) { unsigned long hash; -- 2.25.1
[PATCH 1/4] powerpc/64s: Add DEBUG_PAGEALLOC for radix
There is support for DEBUG_PAGEALLOC on hash but not on radix. Add support on radix. Signed-off-by: Jordan Niethe --- arch/powerpc/include/asm/book3s/32/pgtable.h | 10 arch/powerpc/include/asm/book3s/64/hash.h| 2 ++ arch/powerpc/include/asm/book3s/64/pgtable.h | 19 ++ arch/powerpc/include/asm/book3s/64/radix.h | 2 ++ arch/powerpc/include/asm/nohash/pgtable.h| 10 arch/powerpc/include/asm/set_memory.h| 2 ++ arch/powerpc/mm/book3s64/hash_utils.c| 2 +- arch/powerpc/mm/book3s64/radix_pgtable.c | 26 ++-- arch/powerpc/mm/pageattr.c | 6 + 9 files changed, 76 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h index 83c65845a1a9..30533d409f7f 100644 --- a/arch/powerpc/include/asm/book3s/32/pgtable.h +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h @@ -417,6 +417,16 @@ static inline unsigned long pte_pfn(pte_t pte) } /* Generic modifiers for PTE bits */ +static inline pte_t pte_mkabsent(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_PRESENT); +} + +static inline pte_t pte_mkpresent(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_PRESENT); +} + static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_RW); diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index d959b0195ad9..f6171633cdc2 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -179,6 +179,8 @@ static inline unsigned long hash__pte_update(struct mm_struct *mm, return old; } +void hash__kernel_map_pages(struct page *page, int numpages, int enable); + /* Set the dirty and/or accessed bits atomically in a linux PTE, this * function doesn't need to flush the hash entry */ diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index a666d561b44d..b89482aed82a 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -651,6 +651,16 @@ static inline unsigned long pte_pfn(pte_t pte) } /* Generic modifiers for PTE bits */ +static inline pte_t pte_mkabsent(pte_t pte) +{ + return __pte_raw(pte_raw(pte) & cpu_to_be64(~_PAGE_PRESENT)); +} + +static inline pte_t pte_mkpresent(pte_t pte) +{ + return __pte_raw(pte_raw(pte) | cpu_to_be64(_PAGE_PRESENT)); +} + static inline pte_t pte_wrprotect(pte_t pte) { if (unlikely(pte_savedwrite(pte))) @@ -812,6 +822,15 @@ static inline bool check_pte_access(unsigned long access, unsigned long ptev) * Generic functions with hash/radix callbacks */ +#ifdef CONFIG_DEBUG_PAGEALLOC +static inline void __kernel_map_pages(struct page *page, int numpages, int enable) +{ + if (radix_enabled()) + radix__kernel_map_pages(page, numpages, enable); + hash__kernel_map_pages(page, numpages, enable); +} +#endif + static inline void __ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep, pte_t entry, unsigned long address, diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h index 59cab558e2f0..d4fa28a77cc6 100644 --- a/arch/powerpc/include/asm/book3s/64/radix.h +++ b/arch/powerpc/include/asm/book3s/64/radix.h @@ -137,6 +137,8 @@ extern void radix__mark_rodata_ro(void); extern void radix__mark_initmem_nx(void); #endif +void radix__kernel_map_pages(struct page *page, int numpages, int enable); + extern void radix__ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep, pte_t entry, unsigned long address, int psize); diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h index ac75f4ab0dba..2a57bbb5820a 100644 --- a/arch/powerpc/include/asm/nohash/pgtable.h +++ b/arch/powerpc/include/asm/nohash/pgtable.h @@ -125,6 +125,16 @@ static inline unsigned long pte_pfn(pte_t pte) { return pte_val(pte) >> PTE_RPN_SHIFT; } /* Generic modifiers for PTE bits */ +static inline pte_t pte_mkabsent(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_PRESENT); +} + +static inline pte_t pte_mkpresent(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_PRESENT); +} + static inline pte_t pte_exprotect(pte_t pte) { return __pte(pte_val(pte) & ~_PAGE_EXEC); diff --git a/arch/powerpc/include/asm/set_memory.h b/arch/powerpc/include/asm/set_memory.h index b040094f7920..4b6dfaad4cc9 100644 --- a/arch/powerpc/include/asm/set_memory.h +++ b/arch/powerpc/include/asm/set_memory.h @@ -6,6 +6,8 @@ #define SET_MEMORY_RW 1 #define SET_MEMORY_NX 2 #define SET_MEMORY_X 3 +#define SET_MEMORY_EN 4 +#define SET_MEMORY_DIS 5 int change_
[PATCH 0/4] powerpc/64s: Enable KFENCE
This adds support for radix to Christophe's series that enabled KFENCE on powerpc/64s/hash: https://lore.kernel.org/linuxppc-dev/8dfe1bd2abde26337c1d8c1ad0acfcc82185e0d5.1614868445.git.christophe.le...@csgroup.eu/ First implement DEBUG_PAGEALLOC for radix so KFENCE can reuse the same infrastructure. This requires the "powerpc: Further Strict RWX support" series: https://lore.kernel.org/linuxppc-dev/20210517032810.129949-1-jniet...@gmail.com/ Christophe Leroy (3): powerpc/64s: Remove unneeded #ifdef CONFIG_DEBUG_PAGEALLOC in hash_utils powerpc/64s: Allow double call of kernel_[un]map_linear_page() powerpc: Enable KFENCE on BOOK3S/64 Jordan Niethe (1): powerpc/64s: Add DEBUG_PAGEALLOC for radix arch/powerpc/Kconfig | 2 +- arch/powerpc/include/asm/book3s/32/pgtable.h | 10 +++ arch/powerpc/include/asm/book3s/64/hash.h| 2 ++ arch/powerpc/include/asm/book3s/64/pgtable.h | 19 arch/powerpc/include/asm/book3s/64/radix.h | 2 ++ arch/powerpc/include/asm/kfence.h| 19 arch/powerpc/include/asm/nohash/pgtable.h| 10 +++ arch/powerpc/include/asm/set_memory.h| 2 ++ arch/powerpc/mm/book3s64/hash_utils.c| 31 ++-- arch/powerpc/mm/book3s64/radix_pgtable.c | 28 -- arch/powerpc/mm/pageattr.c | 6 11 files changed, 113 insertions(+), 18 deletions(-) -- 2.25.1
Re: [PATCH] [v2] selftests: powerpc: Remove unneeded variables
Wan Jiabing writes: > Fix coccicheck warning: > > ./tools/testing/selftests/powerpc/alignment/alignment_handler.c:539:5-7: > Unneeded variable: "rc". Return "0" on line 562 > ./tools/testing/selftests/powerpc/alignment/alignment_handler.c:567:5-7: > Unneeded variable: "rc". Return "0" on line 580 > ./tools/testing/selftests/powerpc/alignment/alignment_handler.c:585:5-7: > Unneeded variable: "rc". Return "0" on line 594 > ./tools/testing/selftests/powerpc/alignment/alignment_handler.c:600:5-7: > Unneeded variable: "rc". Return "0" on line 611 > ./tools/testing/selftests/powerpc/alignment/alignment_handler.c:416:5-7: > Unneeded variable: "rc". Return "0" on line 470 > ./tools/testing/selftests/powerpc/alignment/alignment_handler.c:475:5-7: > Unneeded variable: "rc". Return "0" on line 485 > ./tools/testing/selftests/powerpc/alignment/alignment_handler.c:490:5-7: > Unneeded variable: "rc". Return "0" on line 506 > ./tools/testing/selftests/powerpc/alignment/alignment_handler.c:511:5-7: > Unneeded variable: "rc". Return "0" on line 534 > ./tools/testing/selftests/powerpc/alignment/alignment_handler.c:331:5-7: > Unneeded variable: "rc". Return "0" on line 344 > ./tools/testing/selftests/powerpc/alignment/alignment_handler.c:349:5-7: > Unneeded variable: "rc". Return "0" on line 360 > ./tools/testing/selftests/powerpc/alignment/alignment_handler.c:365:5-7: > Unneeded variable: "rc". Return "0" on line 392 > ./tools/testing/selftests/powerpc/alignment/alignment_handler.c:397:5-7: > Unneeded variable: "rc". Return "0" on line 411 > > Signed-off-by: Wan Jiabing > --- > Changelog: > v2: > - Modify the subject line. > --- > .../powerpc/alignment/alignment_handler.c | 48 +-- > 1 file changed, 12 insertions(+), 36 deletions(-) This breaks the build. Please don't send selftest patches you haven't even build tested. cheers powerpc64le-linux-gnu-gcc -std=gnu99 -O2 -Wall -Werror -DGIT_VERSION='"v5.13-rc2-30-g0510571fcf78"' -I/linux/tools/testing/selftests/powerpc/include alignment_handler.c ../harness.c ../utils.c -o /output/kselftest/powerpc/alignment/alignment_handler alignment_handler.c: In function 'test_alignment_handler_vsx_206': alignment_handler.c:93:2: error: 'rc' undeclared (first use in this function) 93 | rc |= do_test(#name, test_##name) | ^~ alignment_handler.c:106:33: note: in expansion of macro 'TEST' 106 | #define LOAD_VSX_XFORM_TEST(op) TEST(op, op, stxvd2x, XFORM, 32, 32) | ^~~~ alignment_handler.c:326:2: note: in expansion of macro 'LOAD_VSX_XFORM_TEST' 326 | LOAD_VSX_XFORM_TEST(lxvd2x); | ^~~ alignment_handler.c:93:2: note: each undeclared identifier is reported only once for each function it appears in 93 | rc |= do_test(#name, test_##name) | ^~ alignment_handler.c:106:33: note: in expansion of macro 'TEST' 106 | #define LOAD_VSX_XFORM_TEST(op) TEST(op, op, stxvd2x, XFORM, 32, 32) | ^~~~ alignment_handler.c:326:2: note: in expansion of macro 'LOAD_VSX_XFORM_TEST' 326 | LOAD_VSX_XFORM_TEST(lxvd2x); | ^~~ alignment_handler.c: In function 'test_alignment_handler_vsx_207': alignment_handler.c:93:2: error: 'rc' undeclared (first use in this function) 93 | rc |= do_test(#name, test_##name) | ^~ alignment_handler.c:106:33: note: in expansion of macro 'TEST' 106 | #define LOAD_VSX_XFORM_TEST(op) TEST(op, op, stxvd2x, XFORM, 32, 32) | ^~~~ alignment_handler.c:342:2: note: in expansion of macro 'LOAD_VSX_XFORM_TEST' 342 | LOAD_VSX_XFORM_TEST(lxsspx); | ^~~ alignment_handler.c: In function 'test_alignment_handler_vsx_300': alignment_handler.c:93:2: error: 'rc' undeclared (first use in this function) 93 | rc |= do_test(#name, test_##name) | ^~ alignment_handler.c:112:33: note: in expansion of macro 'TEST' 112 | #define LOAD_VMX_DFORM_TEST(op) TEST(op, op, stxv, DFORM, 0, 32) | ^~~~ alignment_handler.c:356:2: note: in expansion of macro 'LOAD_VMX_DFORM_TEST' 356 | LOAD_VMX_DFORM_TEST(lxsd); | ^~~ alignment_handler.c: In function 'test_alignment_handler_vsx_prefix': alignment_handler.c:104:2: error: 'rc' undeclared (first use in this function) 104 | rc |= do_test(#name, test_##name) | ^~ alignment_handler.c:134:44: note: in expansion of macro 'TESTP' 134 | #define LOAD_VSX_8LS_PREFIX_TEST(op, tail) TESTP(op, op, PSTXV ## tail, 0, 32) |^ alignment_handler.c:386:2: note: in expansion of macro 'LOAD_VSX_8LS_PREFIX_TEST' 386 | LOAD_VSX_8LS_PREFIX_TEST(PLXSD, 0); | ^~~~ alignment_handler.c: In function 'test_alignment_handler_integer': alignment_handler.c:93:2: error: 'rc' undeclared (first use in this function) 93 | rc |= do_test(#name, test_##name) | ^~ alignment_handler.
Re: Fwd: [Bug 213069] New: kernel BUG at arch/powerpc/include/asm/book3s/64/hash-4k.h:147! Oops: Exception in kernel mode, sig: 5 [#1]
On 5/17/21 11:17 AM, Christophe Leroy wrote: +aneesh +linuxppc-dev list Le 17/05/2021 à 07:44, Anshuman Khandual a écrit : Hello Christophe, DEBUG_VM_PGTABLE has now been re-enabled on powerpc recently ? was not aware about this. From the error log, it failed explicitly on 4K page size hash config. static inline pmd_t hash__pmd_mkhuge(pmd_t pmd) { BUG(); --> Failed return pmd; } static inline pmd_t __pmd_mkhuge(pmd_t pmd) { if (radix_enabled()) return radix__pmd_mkhuge(pmd); return hash__pmd_mkhuge(pmd); } pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot) { unsigned long pmdv; pmdv = (pfn << PAGE_SHIFT) & PTE_RPN_MASK; return __pmd_mkhuge(pmd_set_protbits(__pmd(pmdv), pgprot)); } It seems like on powerpc, where pfn_pmd() makes a huge page but which is not supported on 4K hash config thus triggering the BUG(). But all pfn_pmd() call sites inside the debug_vm_pgtable() test are protected with CONFIG_TRANSPARENT_HUGEPAGE. IIUC unlike powerpc, pfn_pmd() does not directly make a huge page on other platforms. Looking at arch/powerpc/include/asm/book3s/64/hash-4k.h, all relevant THP helpers has BUG() or 0 which indicates THP might not be supported on 4K page size hash config ? But looking at arch/powerpc/platforms/Kconfig.cputype, it seems like HAVE_ARCH_TRANSPARENT_HUGEPAGE is invariably selected on PPC_BOOK3S_64 platforms which I assume includes 4K page size hash config as well. Is THP some how getting enabled on this 4K page size hash config where it should not be (thus triggering the BUG) ? OR am I missing something here. We should put those pfn_pmd() and pfn_pud() after if (!has_transparent_hugepage()) return; On hash with 4K page size, we can't support leaf page table entry and PMD and PUD level. Hence we don't support THP for them. -aneesh
Re: Fwd: [Bug 213069] New: kernel BUG at arch/powerpc/include/asm/book3s/64/hash-4k.h:147! Oops: Exception in kernel mode, sig: 5 [#1]
+aneesh +linuxppc-dev list Le 17/05/2021 à 07:44, Anshuman Khandual a écrit : Hello Christophe, DEBUG_VM_PGTABLE has now been re-enabled on powerpc recently ? was not aware about this. From the error log, it failed explicitly on 4K page size hash config. static inline pmd_t hash__pmd_mkhuge(pmd_t pmd) { BUG(); --> Failed return pmd; } static inline pmd_t __pmd_mkhuge(pmd_t pmd) { if (radix_enabled()) return radix__pmd_mkhuge(pmd); return hash__pmd_mkhuge(pmd); } pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot) { unsigned long pmdv; pmdv = (pfn << PAGE_SHIFT) & PTE_RPN_MASK; return __pmd_mkhuge(pmd_set_protbits(__pmd(pmdv), pgprot)); } It seems like on powerpc, where pfn_pmd() makes a huge page but which is not supported on 4K hash config thus triggering the BUG(). But all pfn_pmd() call sites inside the debug_vm_pgtable() test are protected with CONFIG_TRANSPARENT_HUGEPAGE. IIUC unlike powerpc, pfn_pmd() does not directly make a huge page on other platforms. Looking at arch/powerpc/include/asm/book3s/64/hash-4k.h, all relevant THP helpers has BUG() or 0 which indicates THP might not be supported on 4K page size hash config ? But looking at arch/powerpc/platforms/Kconfig.cputype, it seems like HAVE_ARCH_TRANSPARENT_HUGEPAGE is invariably selected on PPC_BOOK3S_64 platforms which I assume includes 4K page size hash config as well. Is THP some how getting enabled on this 4K page size hash config where it should not be (thus triggering the BUG) ? OR am I missing something here. - Anshuman On 5/15/21 7:52 PM, Christophe Leroy wrote: [ cut here ] kernel BUG at arch/powerpc/include/asm/book3s/64/hash-4k.h:147! Oops: Exception in kernel mode, sig: 5 [#1] BE PAGE_SIZE=4K MMU=Hash SMP NR_CPUS=4 NUMA PowerMac Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Tainted: GW 5.13.0-rc1-PowerMacG5 #2 NIP: c003d6fc LR: c1024bc8 CTR: c00f778c REGS: c25f7840 TRAP: 0700 Tainted: GW (5.13.0-rc1-PowerMacG5) MSR: 90029032 CR: 44002448 XER: IRQMASK: 0 GPR00: c1024a5c c25f7ae0 c129f800 c25f7b58 GPR04: 1000 8108 0001 GPR08: 0008 0200 GPR12: 24002440 c2366000 c001003c GPR16: GPR20: c11b3388 c0b013e8 c11b3108 4006 GPR24: 4280 011b3000 8105 GPR28: 1000 ff7f c0b01460 811b3108 NIP [c003d6fc] .pfn_pmd+x0x/0x4 LR [c1024bc8] .debug_vm_pgtable+0x3f4/0x51c Call Trace: [c25f7ae0] [c1024a5c] .debug_vm_pgtable+0x288/0x51c (unreliable) [c25f7bd0] [c000fa58] .do_one_initcall+0x104/0x2c4 [c25f7cb0] [c1003dec] .kernel_init_freeable+0x3d4/0x410 [c25f7da0] [c001004c] .kernel_init+0x10/0x15c [c25f7e10] [c000bbf4] .ret_from_kernel_thread+0x58/0x64 Instruction dump: 4bffcd05 6000 e9210078 e94d0370 7d295279 3940 4182000c 487d3829 6000 38210090 7fe3fb78 487dacf4 <0fe0> 7c0802a6 f8010010 f821ff71 ---[ end trace 21fc0fb84dac9a9b ]---
[PATCH v14 9/9] powerpc/32: use set_memory_attr()
From: Christophe Leroy Use set_memory_attr() instead of the PPC32 specific change_page_attr() change_page_attr() was checking that the address was not mapped by blocks and was handling highmem, but that's unneeded because the affected pages can't be in highmem and block mapping verification is already done by the callers. Signed-off-by: Christophe Leroy [ruscur: rebase on powerpc/merge with Christophe's new patches] Signed-off-by: Russell Currey Signed-off-by: Jordan Niethe --- arch/powerpc/mm/pgtable_32.c | 60 ++-- 1 file changed, 10 insertions(+), 50 deletions(-) diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index e0ec67a16887..dcf5ecca19d9 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -132,64 +133,20 @@ void __init mapin_ram(void) } } -static int __change_page_attr_noflush(struct page *page, pgprot_t prot) -{ - pte_t *kpte; - unsigned long address; - - BUG_ON(PageHighMem(page)); - address = (unsigned long)page_address(page); - - if (v_block_mapped(address)) - return 0; - kpte = virt_to_kpte(address); - if (!kpte) - return -EINVAL; - __set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0); - - return 0; -} - -/* - * Change the page attributes of an page in the linear mapping. - * - * THIS DOES NOTHING WITH BAT MAPPINGS, DEBUG USE ONLY - */ -static int change_page_attr(struct page *page, int numpages, pgprot_t prot) -{ - int i, err = 0; - unsigned long flags; - struct page *start = page; - - local_irq_save(flags); - for (i = 0; i < numpages; i++, page++) { - err = __change_page_attr_noflush(page, prot); - if (err) - break; - } - wmb(); - local_irq_restore(flags); - flush_tlb_kernel_range((unsigned long)page_address(start), - (unsigned long)page_address(page)); - return err; -} - void mark_initmem_nx(void) { - struct page *page = virt_to_page(_sinittext); unsigned long numpages = PFN_UP((unsigned long)_einittext) - PFN_DOWN((unsigned long)_sinittext); if (v_block_mapped((unsigned long)_sinittext)) mmu_mark_initmem_nx(); else - change_page_attr(page, numpages, PAGE_KERNEL); + set_memory_attr((unsigned long)_sinittext, numpages, PAGE_KERNEL); } #ifdef CONFIG_STRICT_KERNEL_RWX void mark_rodata_ro(void) { - struct page *page; unsigned long numpages; if (v_block_mapped((unsigned long)_stext + 1)) { @@ -198,20 +155,18 @@ void mark_rodata_ro(void) return; } - page = virt_to_page(_stext); numpages = PFN_UP((unsigned long)_etext) - PFN_DOWN((unsigned long)_stext); - change_page_attr(page, numpages, PAGE_KERNEL_ROX); + set_memory_attr((unsigned long)_stext, numpages, PAGE_KERNEL_ROX); /* * mark .rodata as read only. Use __init_begin rather than __end_rodata * to cover NOTES and EXCEPTION_TABLE. */ - page = virt_to_page(__start_rodata); numpages = PFN_UP((unsigned long)__init_begin) - PFN_DOWN((unsigned long)__start_rodata); - change_page_attr(page, numpages, PAGE_KERNEL_RO); + set_memory_attr((unsigned long)__start_rodata, numpages, PAGE_KERNEL_RO); // mark_initmem_nx() should have already run by now ptdump_check_wx(); @@ -221,9 +176,14 @@ void mark_rodata_ro(void) #ifdef CONFIG_DEBUG_PAGEALLOC void __kernel_map_pages(struct page *page, int numpages, int enable) { + unsigned long addr = (unsigned long)page_address(page); + if (PageHighMem(page)) return; - change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0)); + if (enable) + set_memory_attr(addr, numpages, PAGE_KERNEL); + else + set_memory_attr(addr, numpages, __pgprot(0)); } #endif /* CONFIG_DEBUG_PAGEALLOC */ -- 2.25.1
[PATCH v14 8/9] powerpc/mm: implement set_memory_attr()
From: Christophe Leroy In addition to the set_memory_xx() functions which allows to change the memory attributes of not (yet) used memory regions, implement a set_memory_attr() function to: - set the final memory protection after init on currently used kernel regions. - enable/disable kernel memory regions in the scope of DEBUG_PAGEALLOC. Unlike the set_memory_xx() which can act in three step as the regions are unused, this function must modify 'on the fly' as the kernel is executing from them. At the moment only PPC32 will use it and changing page attributes on the fly is not an issue. Signed-off-by: Christophe Leroy Reported-by: kbuild test robot [ruscur: cast "data" to unsigned long instead of int] Signed-off-by: Russell Currey Signed-off-by: Jordan Niethe --- arch/powerpc/include/asm/set_memory.h | 2 ++ arch/powerpc/mm/pageattr.c| 33 +++ 2 files changed, 35 insertions(+) diff --git a/arch/powerpc/include/asm/set_memory.h b/arch/powerpc/include/asm/set_memory.h index 64011ea444b4..b040094f7920 100644 --- a/arch/powerpc/include/asm/set_memory.h +++ b/arch/powerpc/include/asm/set_memory.h @@ -29,4 +29,6 @@ static inline int set_memory_x(unsigned long addr, int numpages) return change_memory_attr(addr, numpages, SET_MEMORY_X); } +int set_memory_attr(unsigned long addr, int numpages, pgprot_t prot); + #endif diff --git a/arch/powerpc/mm/pageattr.c b/arch/powerpc/mm/pageattr.c index 5e5ae50a7f23..0876216ceee6 100644 --- a/arch/powerpc/mm/pageattr.c +++ b/arch/powerpc/mm/pageattr.c @@ -99,3 +99,36 @@ int change_memory_attr(unsigned long addr, int numpages, long action) return apply_to_existing_page_range(&init_mm, start, size, change_page_attr, (void *)action); } + +/* + * Set the attributes of a page: + * + * This function is used by PPC32 at the end of init to set final kernel memory + * protection. It includes changing the maping of the page it is executing from + * and data pages it is using. + */ +static int set_page_attr(pte_t *ptep, unsigned long addr, void *data) +{ + pgprot_t prot = __pgprot((unsigned long)data); + + spin_lock(&init_mm.page_table_lock); + + set_pte_at(&init_mm, addr, ptep, pte_modify(*ptep, prot)); + flush_tlb_kernel_range(addr, addr + PAGE_SIZE); + + spin_unlock(&init_mm.page_table_lock); + + return 0; +} + +int set_memory_attr(unsigned long addr, int numpages, pgprot_t prot) +{ + unsigned long start = ALIGN_DOWN(addr, PAGE_SIZE); + unsigned long sz = numpages * PAGE_SIZE; + + if (numpages <= 0) + return 0; + + return apply_to_existing_page_range(&init_mm, start, sz, set_page_attr, + (void *)pgprot_val(prot)); +} -- 2.25.1
[PATCH v14 7/9] powerpc: Set ARCH_HAS_STRICT_MODULE_RWX
From: Russell Currey To enable strict module RWX on powerpc, set: CONFIG_STRICT_MODULE_RWX=y You should also have CONFIG_STRICT_KERNEL_RWX=y set to have any real security benefit. ARCH_HAS_STRICT_MODULE_RWX is set to require ARCH_HAS_STRICT_KERNEL_RWX. This is due to a quirk in arch/Kconfig and arch/powerpc/Kconfig that makes STRICT_MODULE_RWX *on by default* in configurations where STRICT_KERNEL_RWX is *unavailable*. Since this doesn't make much sense, and module RWX without kernel RWX doesn't make much sense, having the same dependencies as kernel RWX works around this problem. Book32s/32 processors with a hash mmu (i.e. 604 core) can not set memory protection on a page by page basis so do not enable. Signed-off-by: Russell Currey [jpn: - predicate on !PPC_BOOK3S_604 - make module_alloc() use PAGE_KERNEL protection] Signed-off-by: Jordan Niethe --- v10: - Predicate on !PPC_BOOK3S_604 - Make module_alloc() use PAGE_KERNEL protection v11: - Neaten up v13: Use strict_kernel_rwx_enabled() v14: Make changes to module_alloc() its own commit --- arch/powerpc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index cce0a137b046..cb5d9d862c35 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -140,6 +140,7 @@ config PPC select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64 select ARCH_HAS_SET_MEMORY select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !HIBERNATION) + select ARCH_HAS_STRICT_MODULE_RWX if ARCH_HAS_STRICT_KERNEL_RWX && !PPC_BOOK3S_604 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UACCESS_FLUSHCACHE select ARCH_HAS_COPY_MC if PPC64 -- 2.25.1
[PATCH v14 6/9] powerpc/bpf: Write protect JIT code
Add the necessary call to bpf_jit_binary_lock_ro() to remove write and add exec permissions to the JIT image after it has finished being written. Without CONFIG_STRICT_MODULE_RWX the image will be writable and executable until the call to bpf_jit_binary_lock_ro(). Reviewed-by: Christophe Leroy Signed-off-by: Jordan Niethe --- v10: New to series v11: Remove CONFIG_STRICT_MODULE_RWX conditional --- arch/powerpc/net/bpf_jit_comp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 6c8c268e4fe8..53aefee3fe70 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -237,6 +237,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) fp->jited_len = alloclen; bpf_flush_icache(bpf_hdr, (u8 *)bpf_hdr + (bpf_hdr->pages * PAGE_SIZE)); + bpf_jit_binary_lock_ro(bpf_hdr); if (!fp->is_func || extra_pass) { bpf_prog_fill_jited_linfo(fp, addrs); out_addrs: -- 2.25.1
[PATCH v14 5/9] powerpc/bpf: Remove bpf_jit_free()
Commit 74451e66d516 ("bpf: make jited programs visible in traces") added a default bpf_jit_free() implementation. Powerpc did not use the default bpf_jit_free() as powerpc did not set the images read-only. The default bpf_jit_free() called bpf_jit_binary_unlock_ro() is why it could not be used for powerpc. Commit d53d2f78cead ("bpf: Use vmalloc special flag") moved keeping track of read-only memory to vmalloc. This included removing bpf_jit_binary_unlock_ro(). Therefore there is no reason powerpc needs its own bpf_jit_free(). Remove it. Reviewed-by: Christophe Leroy Signed-off-by: Jordan Niethe --- v11: New to series --- arch/powerpc/net/bpf_jit_comp.c | 12 1 file changed, 12 deletions(-) diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 798ac4350a82..6c8c268e4fe8 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -257,15 +257,3 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) return fp; } - -/* Overriding bpf_jit_free() as we don't set images read-only. */ -void bpf_jit_free(struct bpf_prog *fp) -{ - unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK; - struct bpf_binary_header *bpf_hdr = (void *)addr; - - if (fp->jited) - bpf_jit_binary_free(bpf_hdr); - - bpf_prog_unlock_free(fp); -} -- 2.25.1
[PATCH v14 4/9] powerpc/kprobes: Mark newly allocated probes as ROX
From: Russell Currey Add the arch specific insn page allocator for powerpc. This allocates ROX pages if STRICT_KERNEL_RWX is enabled. These pages are only written to with patch_instruction() which is able to write RO pages. Reviewed-by: Daniel Axtens Signed-off-by: Russell Currey Signed-off-by: Christophe Leroy [jpn: Reword commit message, switch to __vmalloc_node_range()] Signed-off-by: Jordan Niethe --- v9: - vmalloc_exec() no longer exists - Set the page to RW before freeing it v10: - use __vmalloc_node_range() v11: - Neaten up v12: - Switch from __vmalloc_node_range() to module_alloc() v13: Use strict_kernel_rwx_enabled() v14: Use strict_module_rwx_enabled() --- arch/powerpc/kernel/kprobes.c | 17 + 1 file changed, 17 insertions(+) diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 01ab2163659e..937e338053ff 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -19,11 +19,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; @@ -103,6 +105,21 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset) return addr; } +void *alloc_insn_page(void) +{ + void *page; + + page = module_alloc(PAGE_SIZE); + if (!page) + return NULL; + + if (strict_module_rwx_enabled()) { + set_memory_ro((unsigned long)page, 1); + set_memory_x((unsigned long)page, 1); + } + return page; +} + int arch_prepare_kprobe(struct kprobe *p) { int ret = 0; -- 2.25.1
[PATCH v14 3/9] powerpc/modules: Make module_alloc() Strict Module RWX aware
Make module_alloc() use PAGE_KERNEL protections instead of PAGE_KERNEL_EXEX if Strict Module RWX is enabled. Signed-off-by: Jordan Niethe --- v14: - Split out from powerpc: Set ARCH_HAS_STRICT_MODULE_RWX - Add and use strict_module_rwx_enabled() helper --- arch/powerpc/include/asm/mmu.h | 5 + arch/powerpc/kernel/module.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 607168b1aef4..7710bf0cbf8a 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -357,6 +357,11 @@ static inline bool strict_kernel_rwx_enabled(void) return false; } #endif + +static inline bool strict_module_rwx_enabled(void) +{ + return IS_ENABLED(CONFIG_STRICT_MODULE_RWX) && strict_kernel_rwx_enabled(); +} #endif /* !__ASSEMBLY__ */ /* The kernel use the constants below to index in the page sizes array. diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index 3f35c8d20be7..ed04a3ba66fe 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c @@ -92,12 +92,14 @@ int module_finalize(const Elf_Ehdr *hdr, static __always_inline void * __module_alloc(unsigned long size, unsigned long start, unsigned long end) { + pgprot_t prot = strict_module_rwx_enabled() ? PAGE_KERNEL : PAGE_KERNEL_EXEC; + /* * Don't do huge page allocations for modules yet until more testing * is done. STRICT_MODULE_RWX may require extra work to support this * too. */ - return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, PAGE_KERNEL_EXEC, + return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, prot, VM_FLUSH_RESET_PERMS | VM_NO_HUGE_VMAP, NUMA_NO_NODE, __builtin_return_address(0)); } -- 2.25.1
[PATCH v14 2/9] powerpc/lib/code-patching: Set up Strict RWX patching earlier
setup_text_poke_area() is a late init call so it runs before mark_rodata_ro() and after the init calls. This lets all the init code patching simply write to their locations. In the future, kprobes is going to allocate its instruction pages RO which means they will need setup_text__poke_area() to have been already called for their code patching. However, init_kprobes() (which allocates and patches some instruction pages) is an early init call so it happens before setup_text__poke_area(). start_kernel() calls poking_init() before any of the init calls. On powerpc, poking_init() is currently a nop. setup_text_poke_area() relies on kernel virtual memory, cpu hotplug and per_cpu_areas being setup. setup_per_cpu_areas(), boot_cpu_hotplug_init() and mm_init() are called before poking_init(). Turn setup_text_poke_area() into poking_init(). Reviewed-by: Christophe Leroy Reviewed-by: Russell Currey Signed-off-by: Jordan Niethe --- v9: New to series --- arch/powerpc/lib/code-patching.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 870b30d9be2f..15296207e1ba 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -70,14 +70,11 @@ static int text_area_cpu_down(unsigned int cpu) } /* - * Run as a late init call. This allows all the boot time patching to be done - * simply by patching the code, and then we're called here prior to - * mark_rodata_ro(), which happens after all init calls are run. Although - * BUG_ON() is rude, in this case it should only happen if ENOMEM, and we judge - * it as being preferable to a kernel that will crash later when someone tries - * to use patch_instruction(). + * Although BUG_ON() is rude, in this case it should only happen if ENOMEM, and + * we judge it as being preferable to a kernel that will crash later when + * someone tries to use patch_instruction(). */ -static int __init setup_text_poke_area(void) +int __init poking_init(void) { BUG_ON(!cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powerpc/text_poke:online", text_area_cpu_up, @@ -85,7 +82,6 @@ static int __init setup_text_poke_area(void) return 0; } -late_initcall(setup_text_poke_area); /* * This can be called for kernel text or a module. -- 2.25.1
[PATCH v14 1/9] powerpc/mm: Implement set_memory() routines
From: Russell Currey The set_memory_{ro/rw/nx/x}() functions are required for STRICT_MODULE_RWX, and are generally useful primitives to have. This implementation is designed to be generic across powerpc's many MMUs. It's possible that this could be optimised to be faster for specific MMUs. This implementation does not handle cases where the caller is attempting to change the mapping of the page it is executing from, or if another CPU is concurrently using the page being altered. These cases likely shouldn't happen, but a more complex implementation with MMU-specific code could safely handle them. On hash, the linear mapping is not kept in the linux pagetable, so this will not change the protection if used on that range. Currently these functions are not used on the linear map so just WARN for now. apply_to_existing_page_range() does not work on huge pages so for now disallow changing the protection of huge pages. Reviewed-by: Daniel Axtens Signed-off-by: Russell Currey Signed-off-by: Christophe Leroy [jpn: - Allow set memory functions to be used without Strict RWX - Hash: Disallow certain regions - Have change_page_attr() take function pointers to manipulate ptes - Radix: Add ptesync after set_pte_at()] Signed-off-by: Jordan Niethe --- v10: WARN if trying to change the hash linear map v11: - Update copywrite dates - Allow set memory functions to be used without Strict RWX - Hash: Disallow certain regions and add comment explaining why - Have change_page_attr() take function pointers to manipulate ptes - Clarify change_page_attr()'s comment - Radix: Add ptesync after set_pte_at() v12: - change_page_attr() back to taking an action value - disallow operating on huge pages v14: - only check is_vm_area_hugepages() for virtual memory --- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/set_memory.h | 32 arch/powerpc/mm/Makefile | 2 +- arch/powerpc/mm/pageattr.c| 101 ++ 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/include/asm/set_memory.h create mode 100644 arch/powerpc/mm/pageattr.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 3f863dd21374..cce0a137b046 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -138,6 +138,7 @@ config PPC select ARCH_HAS_MEMBARRIER_CALLBACKS select ARCH_HAS_MEMBARRIER_SYNC_CORE select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64 + select ARCH_HAS_SET_MEMORY select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !HIBERNATION) select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UACCESS_FLUSHCACHE diff --git a/arch/powerpc/include/asm/set_memory.h b/arch/powerpc/include/asm/set_memory.h new file mode 100644 index ..64011ea444b4 --- /dev/null +++ b/arch/powerpc/include/asm/set_memory.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_SET_MEMORY_H +#define _ASM_POWERPC_SET_MEMORY_H + +#define SET_MEMORY_RO 0 +#define SET_MEMORY_RW 1 +#define SET_MEMORY_NX 2 +#define SET_MEMORY_X 3 + +int change_memory_attr(unsigned long addr, int numpages, long action); + +static inline int set_memory_ro(unsigned long addr, int numpages) +{ + return change_memory_attr(addr, numpages, SET_MEMORY_RO); +} + +static inline int set_memory_rw(unsigned long addr, int numpages) +{ + return change_memory_attr(addr, numpages, SET_MEMORY_RW); +} + +static inline int set_memory_nx(unsigned long addr, int numpages) +{ + return change_memory_attr(addr, numpages, SET_MEMORY_NX); +} + +static inline int set_memory_x(unsigned long addr, int numpages) +{ + return change_memory_attr(addr, numpages, SET_MEMORY_X); +} + +#endif diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index c3df3a8501d4..9142cf1fb0d5 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -5,7 +5,7 @@ ccflags-$(CONFIG_PPC64):= $(NO_MINIMAL_TOC) -obj-y := fault.o mem.o pgtable.o mmap.o maccess.o \ +obj-y := fault.o mem.o pgtable.o mmap.o maccess.o pageattr.o \ init_$(BITS).o pgtable_$(BITS).o \ pgtable-frag.o ioremap.o ioremap_$(BITS).o \ init-common.o mmu_context.o drmem.o \ diff --git a/arch/powerpc/mm/pageattr.c b/arch/powerpc/mm/pageattr.c new file mode 100644 index ..5e5ae50a7f23 --- /dev/null +++ b/arch/powerpc/mm/pageattr.c @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * MMU-generic set_memory implementation for powerpc + * + * Copyright 2019-2021, IBM Corporation. + */ + +#include +#include +#include + +#include +#include +#include + + +/* + * Updates the attributes of a page in three ste
[PATCH v14 0/9] powerpc: Further Strict RWX support
Adding more Strict RWX support on powerpc, in particular Strict Module RWX. Thanks for all of the feedback everyone. It is now rebased on linux-next + powerpc/64s/radix: Enable huge vmalloc mappings (https://lore.kernel.org/linuxppc-dev/20210503091755.613393-1-npig...@gmail.com/) For reference the previous revision is available here: https://lore.kernel.org/linuxppc-dev/20210510011828.4006623-1-jniet...@gmail.com/ The changes in v14 for each patch: Christophe Leroy (2): powerpc/mm: implement set_memory_attr() powerpc/32: use set_memory_attr() Jordan Niethe (4): powerpc/lib/code-patching: Set up Strict RWX patching earlier powerpc/modules: Make module_alloc() Strict Module RWX aware v14: - Split out from powerpc: Set ARCH_HAS_STRICT_MODULE_RW - Add and use strict_module_rwx_enabled() helper powerpc/bpf: Remove bpf_jit_free() powerpc/bpf: Write protect JIT code Russell Currey (3): powerpc/mm: Implement set_memory() routines v14: - only check is_vm_area_hugepages() for virtual memory powerpc/kprobes: Mark newly allocated probes as ROX v14: - Use strict_module_rwx_enabled() powerpc: Set ARCH_HAS_STRICT_MODULE_RWX v14: - Make changes to module_alloc() its own commit arch/powerpc/Kconfig | 2 + arch/powerpc/include/asm/mmu.h| 5 + arch/powerpc/include/asm/set_memory.h | 34 +++ arch/powerpc/kernel/kprobes.c | 17 arch/powerpc/kernel/module.c | 4 +- arch/powerpc/lib/code-patching.c | 12 +-- arch/powerpc/mm/Makefile | 2 +- arch/powerpc/mm/pageattr.c| 134 ++ arch/powerpc/mm/pgtable_32.c | 60 ++-- arch/powerpc/net/bpf_jit_comp.c | 13 +-- 10 files changed, 211 insertions(+), 72 deletions(-) create mode 100644 arch/powerpc/include/asm/set_memory.h create mode 100644 arch/powerpc/mm/pageattr.c -- 2.25.1
Re: [PATCH kernel v3] powerpc/makefile: Do not redefine $(CPP) for preprocessor
On 5/14/21 18:46, Segher Boessenkool wrote: Hi! On Fri, May 14, 2021 at 11:42:32AM +0900, Masahiro Yamada wrote: In my best guess, the reason why powerpc adding the endian flag to CPP is this line in arch/powerpc/kernel/vdso64/vdso64.lds.S #ifdef __LITTLE_ENDIAN__ OUTPUT_FORMAT("elf64-powerpcle", "elf64-powerpcle", "elf64-powerpcle") #else OUTPUT_FORMAT("elf64-powerpc", "elf64-powerpc", "elf64-powerpc") #endif Which is equivalent to #ifdef __LITTLE_ENDIAN__ OUTPUT_FORMAT("elf64-powerpcle") #else OUTPUT_FORMAT("elf64-powerpc") #endif so please change that at the same time if you touch this :-) "If you touch this" approach did not work well with this patch so sorry but no ;) and for a separate patch, I'll have to dig since when it is equal, do you know? __LITTLE_ENDIAN__ is defined by powerpc gcc and clang. This predefined macro is required by the newer ABIs, but all older That's good so I'll stick to it. compilers have it as well. _LITTLE_ENDIAN is not supported on all platforms (but it is if your compiler targets Linux, which you cannot necessarily rely on). These macros are PowerPC-specific. For GCC, for all targets, you can say #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ You do not need any of the other *ORDER__ macros in most cases. See "info cpp" for the sordid details. [2] powerpc-linux-gnu-gcc + -mlittle-endian-> __LITTLE_ENDIAN__ is defined You can just write -mbig and -mlittle btw. Those aren't available on all targets, but neither are the long-winded -m{big,little}-endian option names. Pet peeve, I know :-) I am looking the same guarantees across modern enough gcc and clang and I am not sure all of the above is valid for clang 10.0.something (or whatever we say we support) ;) -- Alexey
Re: [PATCH V2 1/1] powerpc/perf: Fix PMU callbacks to clear pending PMI before resetting an overflown PMC
Sorry I missed this :( Excerpts from Athira Rajeev's message of April 20, 2021 1:01 pm: > Running perf fuzzer showed below in dmesg logs: > "Can't find PMC that caused IRQ" > > This means a PMU exception happened, but none of the PMC's (Performance > Monitor Counter) were found to be overflown. There are some corner cases > that clears the PMCs after PMI gets masked. In such cases, the perf > interrupt handler will not find the active PMC values that had caused > the overflow and thus leads to this message while replaying. > > Case 1: PMU Interrupt happens during replay of other interrupts and > counter values gets cleared by PMU callbacks before replay: > > During replay of interrupts like timer, __do_irq and doorbell exception, we > conditionally enable interrupts via may_hard_irq_enable(). This could > potentially create a window to generate a PMI. Since irq soft mask is set > to ALL_DISABLED, the PMI will get masked here. We could get IPIs run before > perf interrupt is replayed and the PMU events could deleted or stopped. > This will change the PMU SPR values and resets the counters. Snippet of > ftrace log showing PMU callbacks invoked in "__do_irq": > > -0 [051] dns. 132025441306354: __do_irq <-call_do_irq > -0 [051] dns. 132025441306430: irq_enter <-__do_irq > -0 [051] dns. 132025441306503: irq_enter_rcu <-__do_irq > -0 [051] dnH. 132025441306599: xive_get_irq <-__do_irq > <<>> > -0 [051] dnH. 132025441307770: > generic_smp_call_function_single_interrupt <-smp_ipi_demux_relaxed > -0 [051] dnH. 132025441307839: flush_smp_call_function_queue > <-smp_ipi_demux_relaxed > -0 [051] dnH. 132025441308057: _raw_spin_lock <-event_function > -0 [051] dnH. 132025441308206: power_pmu_disable <-perf_pmu_disable > -0 [051] dnH. 132025441308337: power_pmu_del <-event_sched_out > -0 [051] dnH. 132025441308407: power_pmu_read <-power_pmu_del > -0 [051] dnH. 132025441308477: read_pmc <-power_pmu_read > -0 [051] dnH. 132025441308590: isa207_disable_pmc <-power_pmu_del > -0 [051] dnH. 132025441308663: write_pmc <-power_pmu_del > -0 [051] dnH. 132025441308787: power_pmu_event_idx > <-perf_event_update_userpage > -0 [051] dnH. 132025441308859: rcu_read_unlock_strict > <-perf_event_update_userpage > -0 [051] dnH. 132025441308975: power_pmu_enable <-perf_pmu_enable > <<>> > -0 [051] dnH. 132025441311108: irq_exit <-__do_irq > -0 [051] dns. 132025441311319: performance_monitor_exception > <-replay_soft_interrupts > > Case 2: PMI's masked during local_* operations, example local_add. > If the local_add operation happens within a local_irq_save, replay of > PMI will be during local_irq_restore. Similar to case 1, this could > also create a window before replay where PMU events gets deleted or > stopped. > > Patch adds a fix to update the PMU callback functions (del,stop,enable) to > check for pending perf interrupt. If there is an overflown PMC and pending > perf interrupt indicated in Paca or by PMAO bit set in MMCR0, clear the PMI > bit in paca to drop that sample. Also clear the MMCR0 PMAO bit which > otherwise could lead to spurious interrupts in some corner cases. Example, > a timer after power_pmu_del which will re-enable interrupts since PMI is > cleared and triggers a PMI again since PMAO bit is still set. Another > condition occures if had disabled MSR[EE] right before perf interrupt > came in. Re-enabling interrupt will trigger PMI since PMAO is still set. > But fails to find valid overflow if PMC get cleared before enabling EE. > > We can't just replay PMI any time. Hence this approach is preferred rather > than replaying PMI before resetting overflown PMC. Patch also documents > core-book3s on a race condition which can trigger these PMC messages during > idle path in PowerNV. > > Fixes: f442d004806e ("powerpc/64s: Add support to mask perf interrupts and > replay them") > Reported-by: Nageswara R Sastry > Suggested-by: Nicholas Piggin I would say you can leave ^ this line out. You and Maddy did the hard work of coming up with the fix, I just suggested a few minor changes. > Suggested-by: Madhavan Srinivasan > Signed-off-by: Athira Rajeev > --- > arch/powerpc/include/asm/hw_irq.h | 19 > arch/powerpc/perf/core-book3s.c | 77 +++ > 2 files changed, 96 insertions(+) > > diff --git a/arch/powerpc/include/asm/hw_irq.h > b/arch/powerpc/include/asm/hw_irq.h > index 56a98936a6a9..7e192bd8253b 100644 > --- a/arch/powerpc/include/asm/hw_irq.h > +++ b/arch/powerpc/include/asm/hw_irq.h > @@ -215,6 +215,23 @@ static inline bool arch_irqs_disabled(void) > return arch_irqs_disabled_flags(arch_local_save_flags()); > } > > +static inline int get_clear_pmi_irq_pending(void) > +{ > + /* > + * Some corner cases could clear the PMU counter overflow > + * while a masked PMI is pending. One of such case is > + * when a PMI happens during interrupt replay and perf > + * counter values gets cleared by PMU callbacks before > + * replay. So
Re: [PATCH v13 6/8] powerpc: Set ARCH_HAS_STRICT_MODULE_RWX
On Fri, May 14, 2021 at 3:50 PM Christophe Leroy wrote: > > > > Le 10/05/2021 à 03:18, Jordan Niethe a écrit : > > From: Russell Currey > > > > To enable strict module RWX on powerpc, set: > > > > CONFIG_STRICT_MODULE_RWX=y > > > > You should also have CONFIG_STRICT_KERNEL_RWX=y set to have any real > > security benefit. > > > > ARCH_HAS_STRICT_MODULE_RWX is set to require ARCH_HAS_STRICT_KERNEL_RWX. > > This is due to a quirk in arch/Kconfig and arch/powerpc/Kconfig that > > makes STRICT_MODULE_RWX *on by default* in configurations where > > STRICT_KERNEL_RWX is *unavailable*. > > > > Since this doesn't make much sense, and module RWX without kernel RWX > > doesn't make much sense, having the same dependencies as kernel RWX > > works around this problem. > > > > With STRICT_MODULE_RWX, now make module_alloc() allocate pages with > > KERNEL_PAGE protection rather than KERNEL_PAGE_EXEC. > > > > Book32s/32 processors with a hash mmu (i.e. 604 core) can not set memory > > protection on a page by page basis so do not enable. > > > > Signed-off-by: Russell Currey > > [jpn: - predicate on !PPC_BOOK3S_604 > >- make module_alloc() use PAGE_KERNEL protection] > > Signed-off-by: Jordan Niethe > > --- > > v10: - Predicate on !PPC_BOOK3S_604 > > - Make module_alloc() use PAGE_KERNEL protection > > v11: - Neaten up > > v13: Use strict_kernel_rwx_enabled() > > --- > > arch/powerpc/Kconfig | 1 + > > arch/powerpc/kernel/module.c | 4 +++- > > 2 files changed, 4 insertions(+), 1 deletion(-) > > > > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > > index cce0a137b046..cb5d9d862c35 100644 > > --- a/arch/powerpc/Kconfig > > +++ b/arch/powerpc/Kconfig > > @@ -140,6 +140,7 @@ config PPC > > select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE > > && PPC_BOOK3S_64 > > select ARCH_HAS_SET_MEMORY > > select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) > > && !HIBERNATION) > > + select ARCH_HAS_STRICT_MODULE_RWX if ARCH_HAS_STRICT_KERNEL_RWX > > && !PPC_BOOK3S_604 > > select ARCH_HAS_TICK_BROADCAST if > > GENERIC_CLOCKEVENTS_BROADCAST > > select ARCH_HAS_UACCESS_FLUSHCACHE > > select ARCH_HAS_COPY_MC if PPC64 > > diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c > > index 3f35c8d20be7..f24004635ed5 100644 > > --- a/arch/powerpc/kernel/module.c > > +++ b/arch/powerpc/kernel/module.c > > @@ -92,12 +92,14 @@ int module_finalize(const Elf_Ehdr *hdr, > > static __always_inline void * > > __module_alloc(unsigned long size, unsigned long start, unsigned long end) > > { > > + pgprot_t prot = strict_kernel_rwx_enabled() ? PAGE_KERNEL : > > PAGE_KERNEL_EXEC; > > + > > I'm not sure this is OK. > > I think we need to make a new helper strict_module_rwx_enabled() because I > don't think we want > PAGE_KERNEL here when CONFIG_STRICT_MODULE_RWX is not selected. Yeah that seems like the right thing to do. I'll send a new version. > > > > /* > >* Don't do huge page allocations for modules yet until more testing > >* is done. STRICT_MODULE_RWX may require extra work to support this > >* too. > >*/ > > - return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, > > PAGE_KERNEL_EXEC, > > + return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, prot, > > VM_FLUSH_RESET_PERMS | VM_NO_HUGE_VMAP, > > NUMA_NO_NODE, > > __builtin_return_address(0)); > > } > >
[powerpc:merge] BUILD SUCCESS 3a81c0495fdb91fd9a9b4f617098c283131eeae1
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git merge branch HEAD: 3a81c0495fdb91fd9a9b4f617098c283131eeae1 Automatic merge of 'fixes' into merge (2021-05-16 08:46) elapsed time: 723m configs tested: 119 configs skipped: 2 The following configs have been built successfully. More configs may be tested in the coming days. gcc tested configs: arm defconfig arm64allyesconfig arm64 defconfig arm allyesconfig arm allmodconfig powerpc mpc832x_rdb_defconfig mips pic32mzda_defconfig ia64generic_defconfig arm viper_defconfig armspear3xx_defconfig arm shannon_defconfig arm lubbock_defconfig armkeystone_defconfig openrisc simple_smp_defconfig mips maltasmvp_defconfig powerpc ppa8548_defconfig sh apsh4a3a_defconfig arcvdk_hs38_smp_defconfig powerpc ppc64e_defconfig sh sh7770_generic_defconfig mipsnlm_xlp_defconfig um x86_64_defconfig powerpc acadia_defconfig powerpc64alldefconfig shsh7757lcr_defconfig powerpc mpc836x_rdk_defconfig sh sdk7780_defconfig m68k amiga_defconfig arm pcm027_defconfig mipsjmr3927_defconfig arc nsimosci_hs_defconfig powerpc mpc8560_ads_defconfig armxcep_defconfig m68k m5275evb_defconfig h8300alldefconfig sh rts7751r2dplus_defconfig powerpcadder875_defconfig arm omap1_defconfig arm pxa910_defconfig sh sh03_defconfig arm aspeed_g5_defconfig sh r7785rp_defconfig powerpc holly_defconfig sparc sparc64_defconfig mips pistachio_defconfig x86_64allnoconfig ia64 allmodconfig ia64defconfig ia64 allyesconfig m68k allmodconfig m68kdefconfig m68k allyesconfig nios2 defconfig arc allyesconfig nds32 allnoconfig nds32 defconfig nios2allyesconfig cskydefconfig alpha defconfig alphaallyesconfig xtensa allyesconfig h8300allyesconfig arc defconfig sh allmodconfig parisc defconfig s390 allyesconfig s390 allmodconfig parisc allyesconfig s390defconfig i386 allyesconfig sparcallyesconfig sparc defconfig i386defconfig mips allyesconfig mips allmodconfig powerpc allyesconfig powerpc allmodconfig powerpc allnoconfig x86_64 randconfig-a004-20210516 x86_64 randconfig-a003-20210516 x86_64 randconfig-a001-20210516 x86_64 randconfig-a005-20210516 x86_64 randconfig-a002-20210516 x86_64 randconfig-a006-20210516 i386 randconfig-a003-20210516 i386 randconfig-a001-20210516 i386 randconfig-a004-20210516 i386 randconfig-a005-20210516 i386 randconfig-a002-20210516 i386 randconfig-a006-20210516 i386 randconfig-a016-20210516 i386 randconfig-a014-20210516 i386 randconfig-a011-20210516 i386 randconfig-a012-20210516 i386 randconfig-a015-20210516 i386 randconfig-a013-20210516 riscvnommu_k210_defconfig riscvallyesconfig riscvnommu_virt_defconfig riscv allnoco
[powerpc:next-test] BUILD SUCCESS 4938c440ff7f2c27641f6639d1202f52759ea3ff
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next-test branch HEAD: 4938c440ff7f2c27641f6639d1202f52759ea3ff powerpc/pseries/ras: Delete a redundant condition branch elapsed time: 723m configs tested: 118 configs skipped: 2 The following configs have been built successfully. More configs may be tested in the coming days. gcc tested configs: arm defconfig arm64allyesconfig arm64 defconfig arm allyesconfig arm allmodconfig powerpc mpc832x_rdb_defconfig mips pic32mzda_defconfig ia64generic_defconfig arm viper_defconfig armspear3xx_defconfig arm shannon_defconfig arm lubbock_defconfig armkeystone_defconfig openrisc simple_smp_defconfig mips maltasmvp_defconfig powerpc ppa8548_defconfig powerpc tqm8541_defconfig armshmobile_defconfig arm stm32_defconfig arm versatile_defconfig mipsnlm_xlr_defconfig shdreamcast_defconfig um x86_64_defconfig powerpc acadia_defconfig powerpc64alldefconfig shsh7757lcr_defconfig powerpc mpc836x_rdk_defconfig sh sdk7780_defconfig m68k amiga_defconfig arm pcm027_defconfig mipsjmr3927_defconfig arc nsimosci_hs_defconfig mips db1xxx_defconfig mipsmaltaup_xpa_defconfig powerpc ksi8560_defconfig mips lemote2f_defconfig powerpc mpc8560_ads_defconfig armxcep_defconfig m68k m5275evb_defconfig h8300alldefconfig sh rts7751r2dplus_defconfig armqcom_defconfig powerpc powernv_defconfig mips loongson1c_defconfig x86_64allnoconfig ia64 allmodconfig ia64defconfig ia64 allyesconfig m68k allmodconfig m68kdefconfig m68k allyesconfig nios2 defconfig arc allyesconfig nds32 allnoconfig nds32 defconfig nios2allyesconfig cskydefconfig alpha defconfig alphaallyesconfig xtensa allyesconfig h8300allyesconfig arc defconfig sh allmodconfig parisc defconfig s390 allyesconfig s390 allmodconfig parisc allyesconfig s390defconfig i386 allyesconfig sparcallyesconfig sparc defconfig i386defconfig mips allyesconfig mips allmodconfig powerpc allyesconfig powerpc allmodconfig powerpc allnoconfig x86_64 randconfig-a004-20210516 x86_64 randconfig-a003-20210516 x86_64 randconfig-a001-20210516 x86_64 randconfig-a005-20210516 x86_64 randconfig-a002-20210516 x86_64 randconfig-a006-20210516 i386 randconfig-a003-20210516 i386 randconfig-a001-20210516 i386 randconfig-a004-20210516 i386 randconfig-a005-20210516 i386 randconfig-a002-20210516 i386 randconfig-a006-20210516 i386 randconfig-a016-20210516 i386 randconfig-a014-20210516 i386 randconfig-a011-20210516 i386 randconfig-a012-20210516 i386 randconfig-a015-20210516 i386 randconfig-a013-20210516 riscvnommu_k210_defconfig riscvallyesconfig riscvnommu_virt_defconfig riscv allnoconfig riscv defconfig riscv