BUG: crash in __tlb_remove_page_size with STRICT_KERNEL_RWX on BOOK3S_32

Christophe Leroy christophe.leroy at c-s.fr
Mon Apr 29 17:31:10 AEST 2019



On 04/26/2019 02:38 PM, Serge Belyshev wrote:
> Hi!
> 
>> Could you please compile your kernel with CONFIG_PPC_PTDUMP, and
>> provide the content of:
>>
>> /sys/kernel/debug/kernel_page_tables
> 
> ---[ Start of kernel VM ]---
> 0xe1000000-0xefffffff  0x21000000       240M        rw       present           dirty  accessed

The above line is not correct, should start at the end of the area 
covered by bats, ie at 0xe0400000 with the current (uncorrect) bats


> ---[ vmalloc() Area ]---

[...]

> 
>> /sys/kernel/debug/powerpc/block_address_translation

[...]

> ---[ Data Block Address Translation ]---
> 0: 0xc0000000-0xc07fffff 0x00000000 Kernel RO coherent
> 1: 0xc0800000-0xc0bfffff 0x00800000 Kernel RO coherent
> 2: 0xc0c00000-0xc13fffff 0x00c00000 Kernel RW coherent
> 3: 0xc1400000-0xc23fffff 0x01400000 Kernel RW coherent
> 4: 0xc2400000-0xc43fffff 0x02400000 Kernel RW coherent
> 5: 0xc4400000-0xc83fffff 0x04400000 Kernel RW coherent
> 6: 0xc8400000-0xd03fffff 0x08400000 Kernel RW coherent
> 7: 0xd0400000-0xe03fffff 0x10400000 Kernel RW coherent

As pointed by Segher, those are not correct, bat 2 for instance should 
be 0xc0c00000-0xc0ffffff

Could you try the below changes ?

commit 5953416b8ef52107e8f04559a08a90aa5368cfcd
Author: Christophe Leroy <christophe.leroy at c-s.fr>
Date:   Mon Apr 29 07:22:08 2019 +0000

     powerpc/32s: fix BATs setting with CONFIG_STRICT_KERNEL_RWX

diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index 8a21958484d8..159bdf0394e6 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -102,7 +102,7 @@ static int find_free_bat(void)
  static unsigned int block_size(unsigned long base, unsigned long top)
  {
  	unsigned int max_size = (cpu_has_feature(CPU_FTR_601) ? 8 : 256) << 20;
-	unsigned int base_shift = (fls(base) - 1) & 31;
+	unsigned int base_shift = (ffs(base) - 1) & 31;
  	unsigned int block_shift = (fls(top - base) - 1) & 31;

  	return min3(max_size, 1U << base_shift, 1U << block_shift);
@@ -158,7 +158,7 @@ static unsigned long __init __mmu_mapin_ram(unsigned 
long base, unsigned long to

  unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
  {
-	int done;
+	unsigned long done;
  	unsigned long border = (unsigned long)__init_begin - PAGE_OFFSET;

  	if (__map_without_bats) {
@@ -170,10 +170,10 @@ unsigned long __init mmu_mapin_ram(unsigned long 
base, unsigned long top)
  		return __mmu_mapin_ram(base, top);

  	done = __mmu_mapin_ram(base, border);
-	if (done != border - base)
+	if (done != border)
  		return done;

-	return done + __mmu_mapin_ram(border, top);
+	return __mmu_mapin_ram(border, top);
  }

  void mmu_mark_initmem_nx(void)


Christophe


More information about the Linuxppc-dev mailing list