Re: [PATCH v14 7/9] powerpc: Set ARCH_HAS_STRICT_MODULE_RWX

2021-05-16 Thread Christophe Leroy




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

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread kajoljain



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

2021-05-16 Thread Christophe Leroy




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

2021-05-16 Thread Christophe Leroy




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]

2021-05-16 Thread bugzilla-daemon
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

2021-05-16 Thread Jordan Niethe
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()

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread Michael Ellerman
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]

2021-05-16 Thread Aneesh Kumar K.V

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]

2021-05-16 Thread Christophe Leroy

+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()

2021-05-16 Thread Jordan Niethe
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()

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread Jordan Niethe
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()

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread Alexey Kardashevskiy




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

2021-05-16 Thread Nicholas Piggin
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

2021-05-16 Thread Jordan Niethe
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

2021-05-16 Thread kernel test robot
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

2021-05-16 Thread kernel test robot
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