linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX
@ 2018-11-29 19:00 Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 01/13] powerpc/mm: add exec protection on powerpc 603 Christophe Leroy
                   ` (12 more replies)
  0 siblings, 13 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

The purpose of this serie is to use BATs with STRICT_KERNEL_RWX
See patch 12 for details.

Christophe Leroy (13):
  powerpc/mm: add exec protection on powerpc 603
  powerpc/mm/32: add base address to mmu_mapin_ram()
  powerpc/mm/32s: rework mmu_mapin_ram()
  powerpc/mm/32s: use generic mmu_mapin_ram() for all blocks.
  powerpc/wii: remove wii_mmu_mapin_mem2()
  powerpc/mm/32s: use _PAGE_EXEC in setbat()
  powerpc/mm/32s: add setibat() clearibat() and update_bats()
  powerpc/32: add helper to write into segment registers
  powerpc/mmu: add is_strict_kernel_rwx() helper
  powerpc/kconfig: define PAGE_SHIFT inside Kconfig
  powerpc/kconfig: define CONFIG_DATA_SHIFT and CONFIG_ETEXT_SHIFT
  powerpc/mm/32s: Use BATs for STRICT_KERNEL_RWX
  powerpc/kconfig: make _etext and data areas alignment configurable on
    Book3s 32

 arch/powerpc/Kconfig                           |  46 +++++++
 arch/powerpc/include/asm/book3s/32/hash.h      |   1 +
 arch/powerpc/include/asm/book3s/32/mmu-hash.h  |   2 +
 arch/powerpc/include/asm/book3s/32/pgtable.h   |  29 ++--
 arch/powerpc/include/asm/cputable.h            |   8 +-
 arch/powerpc/include/asm/mmu.h                 |  11 ++
 arch/powerpc/include/asm/page.h                |  13 +-
 arch/powerpc/include/asm/reg.h                 |   5 +
 arch/powerpc/kernel/head_32.S                  |  37 ++++-
 arch/powerpc/kernel/vmlinux.lds.S              |   9 +-
 arch/powerpc/mm/40x_mmu.c                      |   2 +-
 arch/powerpc/mm/44x_mmu.c                      |   2 +-
 arch/powerpc/mm/8xx_mmu.c                      |   2 +-
 arch/powerpc/mm/dump_linuxpagetables-generic.c |   2 -
 arch/powerpc/mm/fsl_booke_mmu.c                |   2 +-
 arch/powerpc/mm/init_32.c                      |   6 +-
 arch/powerpc/mm/mmu_decl.h                     |  10 +-
 arch/powerpc/mm/pgtable.c                      |  20 +--
 arch/powerpc/mm/pgtable_32.c                   |  35 +++--
 arch/powerpc/mm/ppc_mmu_32.c                   | 178 +++++++++++++++++++++----
 arch/powerpc/platforms/embedded6xx/wii.c       |  24 ----
 21 files changed, 324 insertions(+), 120 deletions(-)

-- 
2.13.3


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v1 01/13] powerpc/mm: add exec protection on powerpc 603
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 02/13] powerpc/mm/32: add base address to mmu_mapin_ram() Christophe Leroy
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

The 603 doesn't have a HASH table, TLB misses are handled by
software. It is then possible to generate page fault when
_PAGE_EXEC is not set like in nohash/32.

There is one "reserved" PTE bit available, this patch uses
it for _PAGE_EXEC.

In order to support it, set_pte_filter() and
set_access_flags_filter() are made common, and the handling
is made dependent on MMU_FTR_HPTE_TABLE

Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/include/asm/book3s/32/hash.h      |  1 +
 arch/powerpc/include/asm/book3s/32/pgtable.h   | 18 +++++++++---------
 arch/powerpc/include/asm/cputable.h            |  8 ++++----
 arch/powerpc/kernel/head_32.S                  |  2 +-
 arch/powerpc/mm/dump_linuxpagetables-generic.c |  2 --
 arch/powerpc/mm/pgtable.c                      | 20 +++++++++++---------
 6 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/hash.h b/arch/powerpc/include/asm/book3s/32/hash.h
index f2892c7ab73e..2a0a467d2985 100644
--- a/arch/powerpc/include/asm/book3s/32/hash.h
+++ b/arch/powerpc/include/asm/book3s/32/hash.h
@@ -26,6 +26,7 @@
 #define _PAGE_WRITETHRU	0x040	/* W: cache write-through */
 #define _PAGE_DIRTY	0x080	/* C: page changed */
 #define _PAGE_ACCESSED	0x100	/* R: page referenced */
+#define _PAGE_EXEC	0x200	/* software: exec allowed */
 #define _PAGE_RW	0x400	/* software: user write access allowed */
 #define _PAGE_SPECIAL	0x800	/* software: Special page */
 
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index c21d33704633..cf844fed4527 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -10,9 +10,9 @@
 /* And here we include common definitions */
 
 #define _PAGE_KERNEL_RO		0
-#define _PAGE_KERNEL_ROX	0
+#define _PAGE_KERNEL_ROX	(_PAGE_EXEC)
 #define _PAGE_KERNEL_RW		(_PAGE_DIRTY | _PAGE_RW)
-#define _PAGE_KERNEL_RWX	(_PAGE_DIRTY | _PAGE_RW)
+#define _PAGE_KERNEL_RWX	(_PAGE_DIRTY | _PAGE_RW | _PAGE_EXEC)
 
 #define _PAGE_HPTEFLAGS _PAGE_HASHPTE
 
@@ -66,11 +66,11 @@ static inline bool pte_user(pte_t pte)
  */
 #define PAGE_NONE	__pgprot(_PAGE_BASE)
 #define PAGE_SHARED	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
-#define PAGE_SHARED_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
+#define PAGE_SHARED_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
 #define PAGE_COPY	__pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_COPY_X	__pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_COPY_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
 #define PAGE_READONLY	__pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_READONLY_X	__pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
 
 /* Permission masks used for kernel mappings */
 #define PAGE_KERNEL	__pgprot(_PAGE_BASE | _PAGE_KERNEL_RW)
@@ -318,7 +318,7 @@ static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
 					   int psize)
 {
 	unsigned long set = pte_val(entry) &
-		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW);
+		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
 
 	pte_update(ptep, 0, set);
 
@@ -384,7 +384,7 @@ static inline int pte_dirty(pte_t pte)		{ return !!(pte_val(pte) & _PAGE_DIRTY);
 static inline int pte_young(pte_t pte)		{ return !!(pte_val(pte) & _PAGE_ACCESSED); }
 static inline int pte_special(pte_t pte)	{ return !!(pte_val(pte) & _PAGE_SPECIAL); }
 static inline int pte_none(pte_t pte)		{ return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; }
-static inline bool pte_exec(pte_t pte)		{ return true; }
+static inline bool pte_exec(pte_t pte)		{ return pte_val(pte) & _PAGE_EXEC; }
 
 static inline int pte_present(pte_t pte)
 {
@@ -451,7 +451,7 @@ static inline pte_t pte_wrprotect(pte_t pte)
 
 static inline pte_t pte_exprotect(pte_t pte)
 {
-	return pte;
+	return __pte(pte_val(pte) & ~_PAGE_EXEC);
 }
 
 static inline pte_t pte_mkclean(pte_t pte)
@@ -466,7 +466,7 @@ static inline pte_t pte_mkold(pte_t pte)
 
 static inline pte_t pte_mkexec(pte_t pte)
 {
-	return pte;
+	return __pte(pte_val(pte) | _PAGE_EXEC);
 }
 
 static inline pte_t pte_mkpte(pte_t pte)
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 29f49a35d6ee..a0395ccbbe9e 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -296,7 +296,7 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTRS_PPC601	(CPU_FTR_COMMON | CPU_FTR_601 | \
 	CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_USE_RTC)
 #define CPU_FTRS_603	(CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
-	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE)
+	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE | CPU_FTR_NOEXECUTE)
 #define CPU_FTRS_604	(CPU_FTR_COMMON | CPU_FTR_PPC_LE)
 #define CPU_FTRS_740_NOTAU	(CPU_FTR_COMMON | \
 	    CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_L2CR | \
@@ -367,15 +367,15 @@ static inline void cpu_feature_keys_init(void) { }
 	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
 	    CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR | \
 	    CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
-#define CPU_FTRS_82XX	(CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE)
+#define CPU_FTRS_82XX	(CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_NOEXECUTE)
 #define CPU_FTRS_G2_LE	(CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
 	    CPU_FTR_MAYBE_CAN_NAP)
 #define CPU_FTRS_E300	(CPU_FTR_MAYBE_CAN_DOZE | \
 	    CPU_FTR_MAYBE_CAN_NAP | \
-	    CPU_FTR_COMMON)
+	    CPU_FTR_COMMON  | CPU_FTR_NOEXECUTE)
 #define CPU_FTRS_E300C2	(CPU_FTR_MAYBE_CAN_DOZE | \
 	    CPU_FTR_MAYBE_CAN_NAP | \
-	    CPU_FTR_COMMON | CPU_FTR_FPU_UNAVAILABLE)
+	    CPU_FTR_COMMON | CPU_FTR_FPU_UNAVAILABLE  | CPU_FTR_NOEXECUTE)
 #define CPU_FTRS_CLASSIC32	(CPU_FTR_COMMON)
 #define CPU_FTRS_8XX	(CPU_FTR_NOEXECUTE)
 #define CPU_FTRS_40X	(CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index 61ca27929355..d1c39b5ccfd6 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -499,7 +499,7 @@ InstructionTLBMiss:
 	lis	r1,PAGE_OFFSET@h		/* check if kernel address */
 	cmplw	0,r1,r3
 	mfspr	r2,SPRN_SPRG_THREAD
-	li	r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
+	li	r1,_PAGE_USER|_PAGE_PRESENT|_PAGE_EXEC /* low addresses tested as user */
 	lwz	r2,PGDIR(r2)
 	bge-	112f
 	mfspr	r2,SPRN_SRR1		/* and MSR_PR bit from SRR1 */
diff --git a/arch/powerpc/mm/dump_linuxpagetables-generic.c b/arch/powerpc/mm/dump_linuxpagetables-generic.c
index 1e3829ec1348..3fe98a0974c6 100644
--- a/arch/powerpc/mm/dump_linuxpagetables-generic.c
+++ b/arch/powerpc/mm/dump_linuxpagetables-generic.c
@@ -21,13 +21,11 @@ static const struct flag_info flag_array[] = {
 		.set	= "rw",
 		.clear	= "r ",
 	}, {
-#ifndef CONFIG_PPC_BOOK3S_32
 		.mask	= _PAGE_EXEC,
 		.val	= _PAGE_EXEC,
 		.set	= " X ",
 		.clear	= "   ",
 	}, {
-#endif
 		.mask	= _PAGE_PRESENT,
 		.val	= _PAGE_PRESENT,
 		.set	= "present",
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 1e33dccbd176..d3d61d29b4f1 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -74,7 +74,7 @@ static struct page *maybe_pte_to_page(pte_t pte)
  * support falls into the same category.
  */
 
-static pte_t set_pte_filter(pte_t pte)
+static pte_t set_pte_filter_hash(pte_t pte)
 {
 	if (radix_enabled())
 		return pte;
@@ -93,14 +93,12 @@ static pte_t set_pte_filter(pte_t pte)
 	return pte;
 }
 
-static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
-				     int dirty)
-{
-	return pte;
-}
-
 #else /* CONFIG_PPC_BOOK3S */
 
+static pte_t set_pte_filter_hash(pte_t pte) { return pte; }
+
+#endif /* CONFIG_PPC_BOOK3S */
+
 /* Embedded type MMU with HW exec support. This is a bit more complicated
  * as we don't have two bits to spare for _PAGE_EXEC and _PAGE_HWEXEC so
  * instead we "filter out" the exec permission for non clean pages.
@@ -109,6 +107,9 @@ static pte_t set_pte_filter(pte_t pte)
 {
 	struct page *pg;
 
+	if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
+		return set_pte_filter_hash(pte);
+
 	/* No exec permission in the first place, move on */
 	if (!pte_exec(pte) || !pte_looks_normal(pte))
 		return pte;
@@ -138,6 +139,9 @@ static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
 {
 	struct page *pg;
 
+	if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
+		return pte;
+
 	/* So here, we only care about exec faults, as we use them
 	 * to recover lost _PAGE_EXEC and perform I$/D$ coherency
 	 * if necessary. Also if _PAGE_EXEC is already set, same deal,
@@ -172,8 +176,6 @@ static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
 	return pte_mkexec(pte);
 }
 
-#endif /* CONFIG_PPC_BOOK3S */
-
 /*
  * set_pte stores a linux PTE into the linux page table.
  */
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v1 02/13] powerpc/mm/32: add base address to mmu_mapin_ram()
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 01/13] powerpc/mm: add exec protection on powerpc 603 Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram() Christophe Leroy
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

At the time being, mmu_mapin_ram() always maps RAM from the beginning.
But some platforms like the WII have to map a second block of RAM.

This patch adds to mmu_mapin_ram() the base address of the block.
At the moment, only base address 0 is supported.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/mm/40x_mmu.c       | 2 +-
 arch/powerpc/mm/44x_mmu.c       | 2 +-
 arch/powerpc/mm/8xx_mmu.c       | 2 +-
 arch/powerpc/mm/fsl_booke_mmu.c | 2 +-
 arch/powerpc/mm/mmu_decl.h      | 2 +-
 arch/powerpc/mm/pgtable_32.c    | 6 +++---
 arch/powerpc/mm/ppc_mmu_32.c    | 2 +-
 7 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/mm/40x_mmu.c b/arch/powerpc/mm/40x_mmu.c
index 61ac468c87c6..b9cf6f8764b0 100644
--- a/arch/powerpc/mm/40x_mmu.c
+++ b/arch/powerpc/mm/40x_mmu.c
@@ -93,7 +93,7 @@ void __init MMU_init_hw(void)
 #define LARGE_PAGE_SIZE_16M	(1<<24)
 #define LARGE_PAGE_SIZE_4M	(1<<22)
 
-unsigned long __init mmu_mapin_ram(unsigned long top)
+unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
 {
 	unsigned long v, s, mapped;
 	phys_addr_t p;
diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
index 12d92518e898..f59df82896a0 100644
--- a/arch/powerpc/mm/44x_mmu.c
+++ b/arch/powerpc/mm/44x_mmu.c
@@ -178,7 +178,7 @@ void __init MMU_init_hw(void)
 	flush_instruction_cache();
 }
 
-unsigned long __init mmu_mapin_ram(unsigned long top)
+unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
 {
 	unsigned long addr;
 	unsigned long memstart = memstart_addr & ~(PPC_PIN_SIZE - 1);
diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c
index 01b7f5107c3a..50b640c7a7f9 100644
--- a/arch/powerpc/mm/8xx_mmu.c
+++ b/arch/powerpc/mm/8xx_mmu.c
@@ -107,7 +107,7 @@ static void __init mmu_patch_cmp_limit(s32 *site, unsigned long mapped)
 	patch_instruction_site(site, instr);
 }
 
-unsigned long __init mmu_mapin_ram(unsigned long top)
+unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
 {
 	unsigned long mapped;
 
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 080d49b26c3a..210cbc1faf63 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -221,7 +221,7 @@ unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx, bool dryrun)
 #error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
 #endif
 
-unsigned long __init mmu_mapin_ram(unsigned long top)
+unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
 {
 	return tlbcam_addrs[tlbcam_index - 1].limit - PAGE_OFFSET + 1;
 }
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 8574fbbc45e0..c29f061b1678 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -130,7 +130,7 @@ extern void wii_memory_fixups(void);
  */
 #ifdef CONFIG_PPC32
 extern void MMU_init_hw(void);
-extern unsigned long mmu_mapin_ram(unsigned long top);
+unsigned long mmu_mapin_ram(unsigned long base, unsigned long top);
 #endif
 
 #ifdef CONFIG_PPC_FSL_BOOK3E
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index bda3c6f1bd32..c030f24d1d05 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -275,15 +275,15 @@ void __init mapin_ram(void)
 
 #ifndef CONFIG_WII
 	top = total_lowmem;
-	s = mmu_mapin_ram(top);
+	s = mmu_mapin_ram(0, top);
 	__mapin_ram_chunk(s, top);
 #else
 	if (!wii_hole_size) {
-		s = mmu_mapin_ram(total_lowmem);
+		s = mmu_mapin_ram(0, total_lowmem);
 		__mapin_ram_chunk(s, total_lowmem);
 	} else {
 		top = wii_hole_start;
-		s = mmu_mapin_ram(top);
+		s = mmu_mapin_ram(0, top);
 		__mapin_ram_chunk(s, top);
 
 		top = memblock_end_of_DRAM();
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index f6f575bae3bc..3a29e88308b0 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -72,7 +72,7 @@ unsigned long p_block_mapped(phys_addr_t pa)
 	return 0;
 }
 
-unsigned long __init mmu_mapin_ram(unsigned long top)
+unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
 {
 	unsigned long tot, bl, done;
 	unsigned long max_size = (256<<20);
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 01/13] powerpc/mm: add exec protection on powerpc 603 Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 02/13] powerpc/mm/32: add base address to mmu_mapin_ram() Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  2018-12-03 21:55   ` Jonathan Neuschäfer
  2018-11-29 19:00 ` [PATCH v1 04/13] powerpc/mm/32s: use generic mmu_mapin_ram() for all blocks Christophe Leroy
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

This patch reworks mmu_mapin_ram() to be more generic and map as much
blocks as possible. It now supports blocks not starting at address 0.

It scans DBATs array to find free ones instead of forcing the use of
BAT2 and BAT3.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/mm/ppc_mmu_32.c | 61 +++++++++++++++++++++++++++++---------------
 1 file changed, 40 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index 3a29e88308b0..61c10ee00ba2 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -72,39 +72,58 @@ unsigned long p_block_mapped(phys_addr_t pa)
 	return 0;
 }
 
+static int find_free_bat(void)
+{
+	int b;
+
+	if (cpu_has_feature(CPU_FTR_601)) {
+		for (b = 0; b < 4; b++) {
+			struct ppc_bat *bat = BATS[b];
+
+			if (!(bat[0].batl & 0x40))
+				return b;
+		}
+	} else {
+		int n = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4;
+
+		for (b = 0; b < n; b++) {
+			struct ppc_bat *bat = BATS[b];
+
+			if (!(bat[1].batu & 3))
+				return b;
+		}
+	}
+	return -1;
+}
+
+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 block_shift = (fls(top - base) - 1) & 31;
+
+	return min3(max_size, 1U << base_shift, 1U << block_shift);
+}
+
 unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
 {
-	unsigned long tot, bl, done;
-	unsigned long max_size = (256<<20);
+	int idx;
 
 	if (__map_without_bats) {
 		printk(KERN_DEBUG "RAM mapped without BATs\n");
 		return 0;
 	}
 
-	/* Set up BAT2 and if necessary BAT3 to cover RAM. */
+	while ((idx = find_free_bat()) != -1 && base != top) {
+		unsigned int size = block_size(base, top);
 
-	/* Make sure we don't map a block larger than the
-	   smallest alignment of the physical address. */
-	tot = top;
-	for (bl = 128<<10; bl < max_size; bl <<= 1) {
-		if (bl * 2 > tot)
+		if (size < 128 << 10)
 			break;
+		setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
+		base += size;
 	}
 
-	setbat(2, PAGE_OFFSET, 0, bl, PAGE_KERNEL_X);
-	done = (unsigned long)bat_addrs[2].limit - PAGE_OFFSET + 1;
-	if ((done < tot) && !bat_addrs[3].limit) {
-		/* use BAT3 to cover a bit more */
-		tot -= done;
-		for (bl = 128<<10; bl < max_size; bl <<= 1)
-			if (bl * 2 > tot)
-				break;
-		setbat(3, PAGE_OFFSET+done, done, bl, PAGE_KERNEL_X);
-		done = (unsigned long)bat_addrs[3].limit - PAGE_OFFSET + 1;
-	}
-
-	return done;
+	return base;
 }
 
 /*
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v1 04/13] powerpc/mm/32s: use generic mmu_mapin_ram() for all blocks.
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
                   ` (2 preceding siblings ...)
  2018-11-29 19:00 ` [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram() Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 05/13] powerpc/wii: remove wii_mmu_mapin_mem2() Christophe Leroy
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

Now that mmu_mapin_ram() is able to handle other blocks
than the one starting at 0, the WII can use it for all
its blocks.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/mm/pgtable_32.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index c030f24d1d05..68a5e2be5343 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -271,26 +271,15 @@ static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
 
 void __init mapin_ram(void)
 {
-	unsigned long s, top;
-
-#ifndef CONFIG_WII
-	top = total_lowmem;
-	s = mmu_mapin_ram(0, top);
-	__mapin_ram_chunk(s, top);
-#else
-	if (!wii_hole_size) {
-		s = mmu_mapin_ram(0, total_lowmem);
-		__mapin_ram_chunk(s, total_lowmem);
-	} else {
-		top = wii_hole_start;
-		s = mmu_mapin_ram(0, top);
-		__mapin_ram_chunk(s, top);
+	struct memblock_region *reg;
+
+	for_each_memblock(memory, reg) {
+		unsigned long base = reg->base;
+		unsigned long top = base + reg->size;
 
-		top = memblock_end_of_DRAM();
-		s = wii_mmu_mapin_mem2(top);
-		__mapin_ram_chunk(s, top);
+		base = mmu_mapin_ram(base, top);
+		__mapin_ram_chunk(base, top);
 	}
-#endif
 }
 
 /* Scan the real Linux page tables and return a PTE pointer for
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v1 05/13] powerpc/wii: remove wii_mmu_mapin_mem2()
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
                   ` (3 preceding siblings ...)
  2018-11-29 19:00 ` [PATCH v1 04/13] powerpc/mm/32s: use generic mmu_mapin_ram() for all blocks Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 06/13] powerpc/mm/32s: use _PAGE_EXEC in setbat() Christophe Leroy
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

wii_mmu_mapin_mem2() is not used anymore, remove it.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/platforms/embedded6xx/wii.c | 24 ------------------------
 1 file changed, 24 deletions(-)

diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c
index ecf703ee3a76..235fe81aa2b1 100644
--- a/arch/powerpc/platforms/embedded6xx/wii.c
+++ b/arch/powerpc/platforms/embedded6xx/wii.c
@@ -54,10 +54,6 @@
 static void __iomem *hw_ctrl;
 static void __iomem *hw_gpio;
 
-unsigned long wii_hole_start;
-unsigned long wii_hole_size;
-
-
 static int __init page_aligned(unsigned long x)
 {
 	return !(x & (PAGE_SIZE-1));
@@ -69,26 +65,6 @@ void __init wii_memory_fixups(void)
 
 	BUG_ON(memblock.memory.cnt != 2);
 	BUG_ON(!page_aligned(p[0].base) || !page_aligned(p[1].base));
-
-	/* determine hole */
-	wii_hole_start = ALIGN(p[0].base + p[0].size, PAGE_SIZE);
-	wii_hole_size = p[1].base - wii_hole_start;
-}
-
-unsigned long __init wii_mmu_mapin_mem2(unsigned long top)
-{
-	unsigned long delta, size, bl;
-	unsigned long max_size = (256<<20);
-
-	/* MEM2 64MB@0x10000000 */
-	delta = wii_hole_start + wii_hole_size;
-	size = top - delta;
-	for (bl = 128<<10; bl < max_size; bl <<= 1) {
-		if (bl * 2 > size)
-			break;
-	}
-	setbat(4, PAGE_OFFSET+delta, delta, bl, PAGE_KERNEL_X);
-	return delta + bl;
 }
 
 static void __noreturn wii_spin(void)
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v1 06/13] powerpc/mm/32s: use _PAGE_EXEC in setbat()
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
                   ` (4 preceding siblings ...)
  2018-11-29 19:00 ` [PATCH v1 05/13] powerpc/wii: remove wii_mmu_mapin_mem2() Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 07/13] powerpc/mm/32s: add setibat() clearibat() and update_bats() Christophe Leroy
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

Do not set IBAT when setbat() is called without _PAGE_EXEC

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/mm/ppc_mmu_32.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index 61c10ee00ba2..1078095d9407 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -130,6 +130,7 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
  * Set up one of the I/D BAT (block address translation) register pairs.
  * The parameters are not checked; in particular size must be a power
  * of 2 between 128k and 256M.
+ * On 603+, only set IBAT when _PAGE_EXEC is set
  */
 void __init setbat(int index, unsigned long virt, phys_addr_t phys,
 		   unsigned int size, pgprot_t prot)
@@ -156,11 +157,12 @@ void __init setbat(int index, unsigned long virt, phys_addr_t phys,
 			bat[1].batu |= 1; 	/* Vp = 1 */
 		if (flags & _PAGE_GUARDED) {
 			/* G bit must be zero in IBATs */
-			bat[0].batu = bat[0].batl = 0;
-		} else {
-			/* make IBAT same as DBAT */
-			bat[0] = bat[1];
+			flags &= ~_PAGE_EXEC;
 		}
+		if (flags & _PAGE_EXEC)
+			bat[0] = bat[1];
+		else
+			bat[0].batu = bat[0].batl = 0;
 	} else {
 		/* 601 cpu */
 		if (bl > BL_8M)
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v1 07/13] powerpc/mm/32s: add setibat() clearibat() and update_bats()
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
                   ` (5 preceding siblings ...)
  2018-11-29 19:00 ` [PATCH v1 06/13] powerpc/mm/32s: use _PAGE_EXEC in setbat() Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 08/13] powerpc/32: add helper to write into segment registers Christophe Leroy
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

setibat() and clearibat() allows to manipulate IBATs independently
of DBATs.

update_bats() allows to update bats after init. This is done
with MMU off.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/include/asm/book3s/32/mmu-hash.h |  2 ++
 arch/powerpc/kernel/head_32.S                 | 35 +++++++++++++++++++++++++++
 arch/powerpc/mm/ppc_mmu_32.c                  | 32 ++++++++++++++++++++++++
 3 files changed, 69 insertions(+)

diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
index e38c91388c40..b4ccb832d4fb 100644
--- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h
+++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
@@ -83,6 +83,8 @@ typedef struct {
 	unsigned long vdso_base;
 } mm_context_t;
 
+void update_bats(void);
+
 #endif /* !__ASSEMBLY__ */
 
 /* We happily ignore the smaller BATs on 601, we don't actually use
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index d1c39b5ccfd6..0f4c72ebb151 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -1101,6 +1101,41 @@ BEGIN_MMU_FTR_SECTION
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
 	blr
 
+_ENTRY(update_bats)
+	lis	r4, 1f@h
+	ori	r4, r4, 1f@l
+	tophys(r4, r4)
+	mfmsr	r6
+	mflr	r7
+	li	r3, MSR_KERNEL & ~(MSR_IR | MSR_DR)
+	rlwinm	r0, r6, 0, ~MSR_RI
+	rlwinm	r0, r0, 0, ~MSR_EE
+	mtmsr	r0
+	mtspr	SPRN_SRR0, r4
+	mtspr	SPRN_SRR1, r3
+	SYNC
+	RFI
+1:	bl	clear_bats
+	lis	r3, BATS@ha
+	addi	r3, r3, BATS@l
+	tophys(r3, r3)
+	LOAD_BAT(0, r3, r4, r5)
+	LOAD_BAT(1, r3, r4, r5)
+	LOAD_BAT(2, r3, r4, r5)
+	LOAD_BAT(3, r3, r4, r5)
+BEGIN_MMU_FTR_SECTION
+	LOAD_BAT(4, r3, r4, r5)
+	LOAD_BAT(5, r3, r4, r5)
+	LOAD_BAT(6, r3, r4, r5)
+	LOAD_BAT(7, r3, r4, r5)
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
+	li	r3, MSR_KERNEL & ~(MSR_IR | MSR_DR | MSR_RI)
+	mtmsr	r3
+	mtspr	SPRN_SRR0, r7
+	mtspr	SPRN_SRR1, r6
+	SYNC
+	RFI
+
 flush_tlbs:
 	lis	r10, 0x40
 1:	addic.	r10, r10, -0x1000
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index 1078095d9407..58dd71686707 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -105,6 +105,38 @@ static unsigned int block_size(unsigned long base, unsigned long top)
 	return min3(max_size, 1U << base_shift, 1U << block_shift);
 }
 
+/*
+ * Set up one of the IBAT (block address translation) register pairs.
+ * The parameters are not checked; in particular size must be a power
+ * of 2 between 128k and 256M.
+ * Only for 603+ ...
+ */
+static void setibat(int index, unsigned long virt, phys_addr_t phys,
+		    unsigned int size, pgprot_t prot)
+{
+	unsigned int bl = (size >> 17) - 1;
+	int wimgxpp;
+	struct ppc_bat *bat = BATS[index];
+	unsigned long flags = pgprot_val(prot);
+
+	if (!cpu_has_feature(CPU_FTR_NEED_COHERENT))
+		flags &= ~_PAGE_COHERENT;
+
+	wimgxpp = (flags & _PAGE_COHERENT) | (_PAGE_EXEC ? BPP_RX : BPP_XX);
+	bat[0].batu = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */
+	bat[0].batl = BAT_PHYS_ADDR(phys) | wimgxpp;
+	if (flags & _PAGE_USER)
+		bat[0].batu |= 1;	/* Vp = 1 */
+}
+
+static void clearibat(int index)
+{
+	struct ppc_bat *bat = BATS[index];
+
+	bat[0].batu = 0;
+	bat[0].batl = 0;
+}
+
 unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
 {
 	int idx;
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v1 08/13] powerpc/32: add helper to write into segment registers
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
                   ` (6 preceding siblings ...)
  2018-11-29 19:00 ` [PATCH v1 07/13] powerpc/mm/32s: add setibat() clearibat() and update_bats() Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 09/13] powerpc/mmu: add is_strict_kernel_rwx() helper Christophe Leroy
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

This patch add an helper which wraps 'mtsrin' instruction
to write into segment registers.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/include/asm/reg.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index de52c3166ba4..c9c382e57017 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1423,6 +1423,11 @@ static inline void msr_check_and_clear(unsigned long bits)
 #define mfsrin(v)	({unsigned int rval; \
 			asm volatile("mfsrin %0,%1" : "=r" (rval) : "r" (v)); \
 					rval;})
+
+static inline void mtsrin(u32 val, u32 idx)
+{
+	asm volatile("mtsrin %0, %1" : : "r" (val), "r" (idx));
+}
 #endif
 
 #define proc_trap()	asm volatile("trap")
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v1 09/13] powerpc/mmu: add is_strict_kernel_rwx() helper
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
                   ` (7 preceding siblings ...)
  2018-11-29 19:00 ` [PATCH v1 08/13] powerpc/32: add helper to write into segment registers Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 10/13] powerpc/kconfig: define PAGE_SHIFT inside Kconfig Christophe Leroy
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

Add a helper to know whether STRICT_KERNEL_RWX is enabled.

This is based on rodata_enabled flag which is defined only
when CONFIG_STRICT_KERNEL_RWX is selected.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/include/asm/mmu.h | 11 +++++++++++
 arch/powerpc/mm/init_32.c      |  4 +---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index eb20eb3b8fb0..6343cbf5b651 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -268,6 +268,17 @@ static inline u16 get_mm_addr_key(struct mm_struct *mm, unsigned long address)
 }
 #endif /* CONFIG_PPC_MEM_KEYS */
 
+#ifdef CONFIG_STRICT_KERNEL_RWX
+static inline bool strict_kernel_rwx_enabled(void)
+{
+	return rodata_enabled;
+}
+#else
+static inline bool strict_kernel_rwx_enabled(void)
+{
+	return false;
+}
+#endif
 #endif /* !__ASSEMBLY__ */
 
 /* The kernel use the constants below to index in the page sizes array.
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 3e59e5d64b01..ee5a430b9a18 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -108,12 +108,10 @@ static void __init MMU_setup(void)
 		__map_without_bats = 1;
 		__map_without_ltlbs = 1;
 	}
-#ifdef CONFIG_STRICT_KERNEL_RWX
-	if (rodata_enabled) {
+	if (strict_kernel_rwx_enabled()) {
 		__map_without_bats = 1;
 		__map_without_ltlbs = 1;
 	}
-#endif
 }
 
 /*
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v1 10/13] powerpc/kconfig: define PAGE_SHIFT inside Kconfig
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
                   ` (8 preceding siblings ...)
  2018-11-29 19:00 ` [PATCH v1 09/13] powerpc/mmu: add is_strict_kernel_rwx() helper Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 11/13] powerpc/kconfig: define CONFIG_DATA_SHIFT and CONFIG_ETEXT_SHIFT Christophe Leroy
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/Kconfig            |  7 +++++++
 arch/powerpc/include/asm/page.h | 13 ++-----------
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 8be31261aec8..4a81a80d0635 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -711,6 +711,13 @@ config PPC_256K_PAGES
 
 endchoice
 
+config PPC_PAGE_SHIFT
+	int
+	default 18 if PPC_256K_PAGES
+	default 16 if PPC_64K_PAGES
+	default 14 if PPC_16K_PAGES
+	default 12
+
 config THREAD_SHIFT
 	int "Thread shift" if EXPERT
 	range 13 15
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 9ea903221a9f..d12a55441629 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -20,20 +20,11 @@
 
 /*
  * On regular PPC32 page size is 4K (but we support 4K/16K/64K/256K pages
- * on PPC44x). For PPC64 we support either 4K or 64K software
+ * on PPC44x and 4K/16K on 8xx). For PPC64 we support either 4K or 64K software
  * page size. When using 64K pages however, whether we are really supporting
  * 64K pages in HW or not is irrelevant to those definitions.
  */
-#if defined(CONFIG_PPC_256K_PAGES)
-#define PAGE_SHIFT		18
-#elif defined(CONFIG_PPC_64K_PAGES)
-#define PAGE_SHIFT		16
-#elif defined(CONFIG_PPC_16K_PAGES)
-#define PAGE_SHIFT		14
-#else
-#define PAGE_SHIFT		12
-#endif
-
+#define PAGE_SHIFT		CONFIG_PPC_PAGE_SHIFT
 #define PAGE_SIZE		(ASM_CONST(1) << PAGE_SHIFT)
 
 #ifndef __ASSEMBLY__
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v1 11/13] powerpc/kconfig: define CONFIG_DATA_SHIFT and CONFIG_ETEXT_SHIFT
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
                   ` (9 preceding siblings ...)
  2018-11-29 19:00 ` [PATCH v1 10/13] powerpc/kconfig: define PAGE_SHIFT inside Kconfig Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 12/13] powerpc/mm/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 13/13] powerpc/kconfig: make _etext and data areas alignment configurable on Book3s 32 Christophe Leroy
  12 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

CONFIG_STRICT_KERNEL_RWX requires a special alignment
for DATA for some subarches. Today it is just defined
as an #ifdef in vmlinux.lds.S

In order to get more flexibility, this patch moves the
definition of this alignment in Kconfig

On some subarches, CONFIG_STRICT_KERNEL_RWX will
require a special alignment of _etext.

This patch also adds a configuration item for it in Kconfig

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/Kconfig              | 9 +++++++++
 arch/powerpc/kernel/vmlinux.lds.S | 9 +++------
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 4a81a80d0635..f3e420f3f1d7 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -728,6 +728,15 @@ config THREAD_SHIFT
 	  Used to define the stack size. The default is almost always what you
 	  want. Only change this if you know what you are doing.
 
+config ETEXT_SHIFT
+	int
+	default PPC_PAGE_SHIFT
+
+config DATA_SHIFT
+	int
+	default 24 if STRICT_KERNEL_RWX && PPC64
+	default PPC_PAGE_SHIFT
+
 config FORCE_MAX_ZONEORDER
 	int "Maximum zone order"
 	range 8 9 if PPC64 && PPC_64K_PAGES
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 1148c3c60c3b..d210dcfe915a 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -12,11 +12,8 @@
 #include <asm/cache.h>
 #include <asm/thread_info.h>
 
-#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(CONFIG_PPC32)
-#define STRICT_ALIGN_SIZE	(1 << 24)
-#else
-#define STRICT_ALIGN_SIZE	PAGE_SIZE
-#endif
+#define STRICT_ALIGN_SIZE	(1 << CONFIG_DATA_SHIFT)
+#define ETEXT_ALIGN_SIZE	(1 << CONFIG_ETEXT_SHIFT)
 
 ENTRY(_stext)
 
@@ -131,7 +128,7 @@ SECTIONS
 
 	} :kernel
 
-	. = ALIGN(PAGE_SIZE);
+	. = ALIGN(ETEXT_ALIGN_SIZE);
 	_etext = .;
 	PROVIDE32 (etext = .);
 
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v1 12/13] powerpc/mm/32s: Use BATs for STRICT_KERNEL_RWX
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
                   ` (10 preceding siblings ...)
  2018-11-29 19:00 ` [PATCH v1 11/13] powerpc/kconfig: define CONFIG_DATA_SHIFT and CONFIG_ETEXT_SHIFT Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  2018-11-29 19:00 ` [PATCH v1 13/13] powerpc/kconfig: make _etext and data areas alignment configurable on Book3s 32 Christophe Leroy
  12 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

Today, STRICT_KERNEL_RWX is based on the use of regular pages
to map kernel pages.

On Book3s 32, it has three consequences:
- Using pages instead of BAT for mapping kernel linear memory severely
impacts performance.
- Exec protection is not effective because no-execute cannot be set at
page level (except on 603 which doesn't have hash tables)
- Write protection is not effective because PP bits do not provide RO
mode for kernel-only pages (except on 603 which handles it in software
via PAGE_DIRTY)

On the 603+, we have:
- Independent IBAT and DBAT allowing limitation of exec parts.
- NX bit can be set in segment registers to forbit execution on memory
mapped by pages.
- RO mode on DBATs even for kernel-only blocks.

On the 601, there is nothing much we can do other than warn the user
about it, because:
- BATs are common to instructions and data.
- BAT do not provide RO mode for kernel-only blocks.
- segment registers don't have the NX bit.

In order to use IBAT for exec protection, this patch:
- Aligns _etext to BAT block sizes (128kb)
- Set NX bit in kernel segment register (Except on vmalloc area when
CONFIG_MODULES is selected)
- Maps kernel text with IBATs.

In order to use DBAT for exec protection, this patch:
- Aligns RW DATA to BAT block sizes (4M)
- Maps kernel RO area with write prohibited DBATs
- Maps remaining memory with remaining DBATs

Here is what we get with this patch on a 832x when activating
STRICT_KERNEL_RWX:

Symbols:
c0000000 T _stext
c0680000 R __start_rodata
c0680000 R _etext
c0800000 T __init_begin
c0800000 T _sinittext

~# cat /sys/kernel/debug/block_address_translation
---[ Instruction Block Address Translation ]---
0: 0xc0000000-0xc03fffff 0x00000000 Kernel EXEC coherent
1: 0xc0400000-0xc05fffff 0x00400000 Kernel EXEC coherent
2: 0xc0600000-0xc067ffff 0x00600000 Kernel EXEC coherent
3:         -
4:         -
5:         -
6:         -
7:         -

---[ Data Block Address Translation ]---
0: 0xc0000000-0xc07fffff 0x00000000 Kernel RO coherent
1: 0xc0800000-0xc0ffffff 0x00800000 Kernel RW coherent
2: 0xc1000000-0xc1ffffff 0x01000000 Kernel RW coherent
3: 0xc2000000-0xc3ffffff 0x02000000 Kernel RW coherent
4: 0xc4000000-0xc7ffffff 0x04000000 Kernel RW coherent
5: 0xc8000000-0xcfffffff 0x08000000 Kernel RW coherent
6: 0xd0000000-0xdfffffff 0x10000000 Kernel RW coherent
7:         -

~# cat /sys/kernel/debug/segment_registers
---[ User Segments ]---
0x00000000-0x0fffffff Kern key 1 User key 1 VSID 0xa085d0
0x10000000-0x1fffffff Kern key 1 User key 1 VSID 0xa086e1
0x20000000-0x2fffffff Kern key 1 User key 1 VSID 0xa087f2
0x30000000-0x3fffffff Kern key 1 User key 1 VSID 0xa08903
0x40000000-0x4fffffff Kern key 1 User key 1 VSID 0xa08a14
0x50000000-0x5fffffff Kern key 1 User key 1 VSID 0xa08b25
0x60000000-0x6fffffff Kern key 1 User key 1 VSID 0xa08c36
0x70000000-0x7fffffff Kern key 1 User key 1 VSID 0xa08d47
0x80000000-0x8fffffff Kern key 1 User key 1 VSID 0xa08e58
0x90000000-0x9fffffff Kern key 1 User key 1 VSID 0xa08f69
0xa0000000-0xafffffff Kern key 1 User key 1 VSID 0xa0907a
0xb0000000-0xbfffffff Kern key 1 User key 1 VSID 0xa0918b

---[ Kernel Segments ]---
0xc0000000-0xcfffffff Kern key 0 User key 1 No Exec VSID 0x000ccc
0xd0000000-0xdfffffff Kern key 0 User key 1 No Exec VSID 0x000ddd
0xe0000000-0xefffffff Kern key 0 User key 1 No Exec VSID 0x000eee
0xf0000000-0xffffffff Kern key 0 User key 1 No Exec VSID 0x000fff

Aligning _etext to 128kb allows to map up to 32Mb text with 8 IBATs:
16Mb + 8Mb + 4Mb + 2Mb + 1Mb + 512kb + 256kb + 128kb (+ 128kb) = 32Mb
(A 9th IBAT is unneeded as 32Mb would need only a single 32Mb block)

Aligning data to 4M allows to map up to 512Mb data with 8 DBATs:
16Mb + 8Mb + 4Mb + 4Mb + 32Mb + 64Mb + 128Mb + 256Mb = 512Mb

Because some processors only have 4 BATs and because some targets need
DBATs for mapping other areas, the following patch will allow to
modify _etext and data alignment.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/Kconfig                         |  2 +
 arch/powerpc/include/asm/book3s/32/pgtable.h | 11 ++++
 arch/powerpc/mm/init_32.c                    |  4 +-
 arch/powerpc/mm/mmu_decl.h                   |  8 +++
 arch/powerpc/mm/pgtable_32.c                 | 10 +++-
 arch/powerpc/mm/ppc_mmu_32.c                 | 87 ++++++++++++++++++++++++++--
 6 files changed, 112 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index f3e420f3f1d7..ffcf4d7a1186 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -730,11 +730,13 @@ config THREAD_SHIFT
 
 config ETEXT_SHIFT
 	int
+	default 17 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
 	default PPC_PAGE_SHIFT
 
 config DATA_SHIFT
 	int
 	default 24 if STRICT_KERNEL_RWX && PPC64
+	default 22 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
 	default PPC_PAGE_SHIFT
 
 config FORCE_MAX_ZONEORDER
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index cf844fed4527..05e973f24446 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -174,7 +174,18 @@ static inline bool pte_user(pte_t pte)
  * of RAM.  -- Cort
  */
 #define VMALLOC_OFFSET (0x1000000) /* 16M */
+
+/*
+ * With CONFIG_STRICT_KERNEL_RWX, kernel segments are set NX. But when modules
+ * are used, NX cannot be set on VMALLOC space. So vmalloc VM space and linear
+ * memory shall not share segments.
+ */
+#if defined(CONFIG_STRICT_KERNEL_RWX) && defined(CONFIG_MODULES)
+#define VMALLOC_START ((_ALIGN((long)high_memory, 256L << 20) + VMALLOC_OFFSET) & \
+		       ~(VMALLOC_OFFSET - 1))
+#else
 #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#endif
 #define VMALLOC_END	ioremap_bot
 
 #ifndef __ASSEMBLY__
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index ee5a430b9a18..bc28995a37ea 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -108,10 +108,8 @@ static void __init MMU_setup(void)
 		__map_without_bats = 1;
 		__map_without_ltlbs = 1;
 	}
-	if (strict_kernel_rwx_enabled()) {
-		__map_without_bats = 1;
+	if (strict_kernel_rwx_enabled())
 		__map_without_ltlbs = 1;
-	}
 }
 
 /*
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index c29f061b1678..ccf994f1c4d2 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -165,3 +165,11 @@ unsigned long p_block_mapped(phys_addr_t pa);
 static inline phys_addr_t v_block_mapped(unsigned long va) { return 0; }
 static inline unsigned long p_block_mapped(phys_addr_t pa) { return 0; }
 #endif
+
+#if defined(CONFIG_PPC_BOOK3S_32)
+void mmu_mark_initmem_nx(void);
+void mmu_mark_rodata_ro(void);
+#else
+static inline void mmu_mark_initmem_nx(void) { }
+static inline void mmu_mark_rodata_ro(void) { }
+#endif
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 68a5e2be5343..c78dba1f961a 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -365,7 +365,10 @@ void mark_initmem_nx(void)
 	unsigned long numpages = PFN_UP((unsigned long)_einittext) -
 				 PFN_DOWN((unsigned long)_sinittext);
 
-	change_page_attr(page, numpages, PAGE_KERNEL);
+	if (v_block_mapped((unsigned long)_stext) + 1)
+		mmu_mark_initmem_nx();
+	else
+		change_page_attr(page, numpages, PAGE_KERNEL);
 }
 
 #ifdef CONFIG_STRICT_KERNEL_RWX
@@ -374,6 +377,11 @@ void mark_rodata_ro(void)
 	struct page *page;
 	unsigned long numpages;
 
+	if (v_block_mapped((unsigned long)_sinittext)) {
+		mmu_mark_rodata_ro();
+		return;
+	}
+
 	page = virt_to_page(_stext);
 	numpages = PFN_UP((unsigned long)_etext) -
 		   PFN_DOWN((unsigned long)_stext);
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index 58dd71686707..83f8ce50169e 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -31,6 +31,7 @@
 #include <asm/prom.h>
 #include <asm/mmu.h>
 #include <asm/machdep.h>
+#include <asm/sections.h>
 
 #include "mmu_decl.h"
 
@@ -137,15 +138,10 @@ static void clearibat(int index)
 	bat[0].batl = 0;
 }
 
-unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
+unsigned long __init __mmu_mapin_ram(unsigned long base, unsigned long top)
 {
 	int idx;
 
-	if (__map_without_bats) {
-		printk(KERN_DEBUG "RAM mapped without BATs\n");
-		return 0;
-	}
-
 	while ((idx = find_free_bat()) != -1 && base != top) {
 		unsigned int size = block_size(base, top);
 
@@ -158,6 +154,85 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
 	return base;
 }
 
+unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
+{
+	int done;
+	unsigned long border = (unsigned long)__init_begin - PAGE_OFFSET;
+
+	if (__map_without_bats) {
+		pr_debug("RAM mapped without BATs\n");
+		return 0;
+	}
+
+	if (!strict_kernel_rwx_enabled() || base >= border || top <= border)
+		return __mmu_mapin_ram(base, top);
+
+	done = __mmu_mapin_ram(base, border);
+	if (done != border - base)
+		return done;
+
+	return done + __mmu_mapin_ram(border, top);
+}
+
+void mmu_mark_initmem_nx(void)
+{
+	int nb = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4;
+	int i;
+	unsigned long base = (unsigned long)_stext - PAGE_OFFSET;
+	unsigned long top = (unsigned long)_etext - PAGE_OFFSET;
+	unsigned long size;
+
+	if (cpu_has_feature(CPU_FTR_601))
+		return;
+
+	for (i = 0; i < nb - 1 && base < top && top - base > (128 << 10);) {
+		size = block_size(base, top);
+		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
+		base += size;
+	}
+	if (base < top) {
+		size = block_size(base, top);
+		size = max(size, 128UL << 10);
+		if ((top - base) > size) {
+			if (strict_kernel_rwx_enabled())
+				pr_warn("Kernel _etext not properly aligned\n");
+			size <<= 1;
+		}
+		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
+		base += size;
+	}
+	for (; i < nb; i++)
+		clearibat(i);
+
+	update_bats();
+
+	for (i = TASK_SIZE >> 28; i < 16; i++) {
+		/* Do not set NX on VM space for modules */
+		if (IS_ENABLED(CONFIG_MODULES) &&
+		    (VMALLOC_START & 0xf0000000) == i << 28)
+			break;
+		mtsrin(mfsrin(i << 28) | 0x10000000, i << 28);
+	}
+}
+
+void mmu_mark_rodata_ro(void)
+{
+	int nb = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4;
+	int i;
+
+	if (cpu_has_feature(CPU_FTR_601))
+		return;
+
+	for (i = 0; i < nb; i++) {
+		struct ppc_bat *bat = BATS[i];
+
+		if (bat_addrs[i].start < (unsigned long)__init_begin)
+			bat[1].batl = (bat[1].batl & ~BPP_RW) | BPP_RX;
+	}
+
+	update_bats();
+}
+
 /*
  * Set up one of the I/D BAT (block address translation) register pairs.
  * The parameters are not checked; in particular size must be a power
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v1 13/13] powerpc/kconfig: make _etext and data areas alignment configurable on Book3s 32
  2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
                   ` (11 preceding siblings ...)
  2018-11-29 19:00 ` [PATCH v1 12/13] powerpc/mm/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
@ 2018-11-29 19:00 ` Christophe Leroy
  12 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-11-29 19:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, j.neuschaefer
  Cc: linux-kernel, linuxppc-dev

Depending on the number of available BATs for mapping the different
kernel areas, it might be needed to increase the alignment of _etext
and/or of data areas.

This patchs allows the user to do it via Kconfig.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/Kconfig | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index ffcf4d7a1186..bab9dab815d9 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -728,16 +728,44 @@ config THREAD_SHIFT
 	  Used to define the stack size. The default is almost always what you
 	  want. Only change this if you know what you are doing.
 
+config ETEXT_SHIFT_BOOL
+	bool "Set custom etext alignment" if STRICT_KERNEL_RWX && PPC_BOOK3S_32
+	depends on ADVANCED_OPTIONS
+	help
+	  This option allows you to set the kernel end of text alignment. When
+	  RAM is mapped by blocks, the alignment needs to fit the size and
+	  number of possible blocks. The default should be OK for most configs.
+
+	  Say N here unless you know what you are doing.
+
 config ETEXT_SHIFT
-	int
+	int "_etext shift" if ETEXT_SHIFT_BOOL
+	range 17 28 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
 	default 17 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
 	default PPC_PAGE_SHIFT
+	help
+	  On Book3S 32 (603+), IBATs are used to map kernel text.
+	  Smaller is the alignment, greater is the number of necessary IBATs.
+
+config DATA_SHIFT_BOOL
+	bool "Set custom data alignment" if STRICT_KERNEL_RWX && PPC_BOOK3S_32
+	depends on ADVANCED_OPTIONS
+	help
+	  This option allows you to set the kernel data alignment. When
+	  RAM is mapped by blocks, the alignment needs to fit the size and
+	  number of possible blocks. The default should be OK for most configs.
+
+	  Say N here unless you know what you are doing.
 
 config DATA_SHIFT
-	int
+	int "Data shift" if DATA_SHIFT_BOOL
 	default 24 if STRICT_KERNEL_RWX && PPC64
+	range 17 28 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
 	default 22 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
 	default PPC_PAGE_SHIFT
+	help
+	  On Book3S 32 (603+), DBATs are used to map kernel text and rodata RO.
+	  Smaller is the alignment, greater is the number of necessary DBATs.
 
 config FORCE_MAX_ZONEORDER
 	int "Maximum zone order"
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-11-29 19:00 ` [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram() Christophe Leroy
@ 2018-12-03 21:55   ` Jonathan Neuschäfer
  2018-12-13 12:16     ` Christophe Leroy
  0 siblings, 1 reply; 27+ messages in thread
From: Jonathan Neuschäfer @ 2018-12-03 21:55 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	j.neuschaefer, linux-kernel, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1538 bytes --]

Hi,

On Thu, Nov 29, 2018 at 07:00:16PM +0000, Christophe Leroy wrote:
> This patch reworks mmu_mapin_ram() to be more generic and map as much
> blocks as possible. It now supports blocks not starting at address 0.
> 
> It scans DBATs array to find free ones instead of forcing the use of
> BAT2 and BAT3.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> ---

I've just tested this series on my Wii, and starting from this patch
(03/13), it hangs at the following lines of output:

[    0.000000] printk: bootconsole [udbg0] enabled
[    0.000000] Total memory = 319MB; using 1024kB for hash table (at (ptrval))

Before this patch it looks like this and boots to userspace:

[    0.000000] printk: bootconsole [udbg0] enabled
[    0.000000] Total memory = 319MB; using 1024kB for hash table (at (ptrval))
[    0.000000] Linux version 4.20.0-rc5-wii-00022-gfbb911b84755 (jn@longitude) (gcc version 8.2.0 (Debian 8.2.0-9)) #1337 PREEMPT Mon Dec 3 21:49:02 CET 2018
ug_udbg_init: early -> final
usbgecko_udbg: ready
[    0.000000] Using wii machine description
...

I've tested at patch 1, 2, 3, 4, and 13, so I don't know if it works
somewhere in the middle, but probably not.

(And in case you're wondering about the 22 in the version string: Those
are mostly patches that give me a serial console.)

I'm not sure what is going on, because I haven't looked closely at the
patches or tried to debug the problem. If you have some debugging tips,
I can try them.


Jonathan Neuschäfer

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-12-03 21:55   ` Jonathan Neuschäfer
@ 2018-12-13 12:16     ` Christophe Leroy
  2018-12-13 14:51       ` Christophe Leroy
  0 siblings, 1 reply; 27+ messages in thread
From: Christophe Leroy @ 2018-12-13 12:16 UTC (permalink / raw)
  To: Jonathan Neuschäfer
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	linux-kernel, linuxppc-dev

Hi,

On 12/03/2018 09:55 PM, Jonathan Neuschäfer wrote:
> Hi,
> 
> On Thu, Nov 29, 2018 at 07:00:16PM +0000, Christophe Leroy wrote:
>> This patch reworks mmu_mapin_ram() to be more generic and map as much
>> blocks as possible. It now supports blocks not starting at address 0.
>>
>> It scans DBATs array to find free ones instead of forcing the use of
>> BAT2 and BAT3.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>> ---
> 
> I've just tested this series on my Wii, and starting from this patch
> (03/13), it hangs at the following lines of output:
> 
> [    0.000000] printk: bootconsole [udbg0] enabled
> [    0.000000] Total memory = 319MB; using 1024kB for hash table (at (ptrval))
> 
> Before this patch it looks like this and boots to userspace:
> 
> [    0.000000] printk: bootconsole [udbg0] enabled
> [    0.000000] Total memory = 319MB; using 1024kB for hash table (at (ptrval))
> [    0.000000] Linux version 4.20.0-rc5-wii-00022-gfbb911b84755 (jn@longitude) (gcc version 8.2.0 (Debian 8.2.0-9)) #1337 PREEMPT Mon Dec 3 21:49:02 CET 2018
> ug_udbg_init: early -> final
> usbgecko_udbg: ready
> [    0.000000] Using wii machine description

Can you tell/provide the .config and dts used ?

You seem to have 319MB RAM wherease arch/powerpc/boot/dts/wii.dts only 
has 88MB Memory:

	memory {
		device_type = "memory";
		reg = <0x00000000 0x01800000	/* MEM1 24MB 1T-SRAM */
		       0x10000000 0x04000000>;	/* MEM2 64MB GDDR3 */
	};

Christophe

> ...
> 
> I've tested at patch 1, 2, 3, 4, and 13, so I don't know if it works
> somewhere in the middle, but probably not.
> 
> (And in case you're wondering about the 22 in the version string: Those
> are mostly patches that give me a serial console.)
> 
> I'm not sure what is going on, because I haven't looked closely at the
> patches or tried to debug the problem. If you have some debugging tips,
> I can try them.
> 
> 
> Jonathan Neuschäfer
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-12-13 12:16     ` Christophe Leroy
@ 2018-12-13 14:51       ` Christophe Leroy
  2018-12-17  1:28         ` Jonathan Neuschäfer
  0 siblings, 1 reply; 27+ messages in thread
From: Christophe Leroy @ 2018-12-13 14:51 UTC (permalink / raw)
  To: Jonathan Neuschäfer; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel

Hi Again,

Le 13/12/2018 à 13:16, Christophe Leroy a écrit :
> Hi,
> 
> On 12/03/2018 09:55 PM, Jonathan Neuschäfer wrote:
>> Hi,
>>
>> On Thu, Nov 29, 2018 at 07:00:16PM +0000, Christophe Leroy wrote:
>>> This patch reworks mmu_mapin_ram() to be more generic and map as much
>>> blocks as possible. It now supports blocks not starting at address 0.
>>>
>>> It scans DBATs array to find free ones instead of forcing the use of
>>> BAT2 and BAT3.
>>>
>>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>>> ---
>>
>> I've just tested this series on my Wii, and starting from this patch
>> (03/13), it hangs at the following lines of output:
>>
>> [    0.000000] printk: bootconsole [udbg0] enabled
>> [    0.000000] Total memory = 319MB; using 1024kB for hash table (at 
>> (ptrval))
>>
>> Before this patch it looks like this and boots to userspace:
>>
>> [    0.000000] printk: bootconsole [udbg0] enabled
>> [    0.000000] Total memory = 319MB; using 1024kB for hash table (at 
>> (ptrval))
>> [    0.000000] Linux version 4.20.0-rc5-wii-00022-gfbb911b84755 
>> (jn@longitude) (gcc version 8.2.0 (Debian 8.2.0-9)) #1337 PREEMPT Mon 
>> Dec 3 21:49:02 CET 2018
>> ug_udbg_init: early -> final
>> usbgecko_udbg: ready
>> [    0.000000] Using wii machine description
> 
> Can you tell/provide the .config and dts used ?
> 
> You seem to have 319MB RAM wherease arch/powerpc/boot/dts/wii.dts only 
> has 88MB Memory:
> 
>      memory {
>          device_type = "memory";
>          reg = <0x00000000 0x01800000    /* MEM1 24MB 1T-SRAM */
>                 0x10000000 0x04000000>;    /* MEM2 64MB GDDR3 */
>      };

Putting the same description in my mpc832x board DTS and doing a few 
hacks to get the WII functions called, I get the following:

[    0.000000] Top of RAM: 0x14000000, Total RAM: 0x5800000
[    0.000000] Memory hole size: 232MB
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x0000000000000000-0x0000000013ffffff]
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x00000000017fffff]
[    0.000000]   node   0: [mem 0x0000000010000000-0x0000000013ffffff]
[    0.000000] Initmem setup node 0 [mem 
0x0000000000000000-0x0000000013ffffff]
[    0.000000] On node 0 totalpages: 22528
[    0.000000]   DMA zone: 640 pages used for memmap
[    0.000000]   DMA zone: 0 pages reserved
[    0.000000]   DMA zone: 22528 pages, LIFO batch:3
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 21888
[    0.000000] Kernel command line: loglevel=7 
ip=192.168.2.5:192.168.2.2::255.0
[    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 
bytes)
[    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Memory: 77060K/90112K available (6548K kernel code, 1156K 
rwdata,
[    0.000000] Kernel virtual memory layout:
[    0.000000]   * 0xfffdf000..0xfffff000  : fixmap
[    0.000000]   * 0xfdffd000..0xfe000000  : early ioremap
[    0.000000]   * 0xd5000000..0xfdffd000  : vmalloc & ioremap




root@vgoippro:~# cat /sys/kernel/debug/powerpc/block_address_translation
---[ Instruction Block Address Translation ]---
0: 0xc0000000-0xc0ffffff 0x00000000 Kernel EXEC coherent
1:         -
2: 0xc1000000-0xc17fffff 0x01000000 Kernel EXEC coherent
3:         -
4: 0xd0000000-0xd3ffffff 0x10000000 Kernel EXEC coherent
5:         -
6:         -
7:         -

---[ Data Block Address Translation ]---
0: 0xc0000000-0xc0ffffff 0x00000000 Kernel RW coherent
1: 0xfffe0000-0xffffffff 0x0d000000 Kernel RW no cache guarded
2: 0xc1000000-0xc17fffff 0x01000000 Kernel RW coherent
3:         -
4: 0xd0000000-0xd3ffffff 0x10000000 Kernel RW coherent
5:         -
6:         -
7:         -


Could you please provide the dmesg and 
/sys/kernel/debug/powerpc/block_address_translation from before this 
patch, so that we can compare and identify the differences if any ?

Thanks
Christophe



> 
> Christophe
> 
>> ...
>>
>> I've tested at patch 1, 2, 3, 4, and 13, so I don't know if it works
>> somewhere in the middle, but probably not.
>>
>> (And in case you're wondering about the 22 in the version string: Those
>> are mostly patches that give me a serial console.)
>>
>> I'm not sure what is going on, because I haven't looked closely at the
>> patches or tried to debug the problem. If you have some debugging tips,
>> I can try them.
>>
>>
>> Jonathan Neuschäfer
>>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-12-13 14:51       ` Christophe Leroy
@ 2018-12-17  1:28         ` Jonathan Neuschäfer
  2018-12-17  9:29           ` Christophe Leroy
  0 siblings, 1 reply; 27+ messages in thread
From: Jonathan Neuschäfer @ 2018-12-17  1:28 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Jonathan Neuschäfer, linuxppc-dev, Paul Mackerras, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 6298 bytes --]

Hi, thanks for your reply.

On Thu, Dec 13, 2018 at 03:51:32PM +0100, Christophe Leroy wrote:
> Hi Again,
> 
> Le 13/12/2018 à 13:16, Christophe Leroy a écrit :
[...]
> > Can you tell/provide the .config and dts used ?

I'm using wii.dts and almost the wii_defconfig from my tree (save-
defconfig result is attached), which is 4.20-rc5 plus a few patches:

  https://github.com/neuschaefer/linux wii-4.20-rc5        (w/o your patches)
  https://github.com/neuschaefer/linux wii-4.20-rc5-ppcbat (w/ your patches 1-3)

> > You seem to have 319MB RAM wherease arch/powerpc/boot/dts/wii.dts only
> > has 88MB Memory:
> > 
> >      memory {
> >          device_type = "memory";
> >          reg = <0x00000000 0x01800000    /* MEM1 24MB 1T-SRAM */
> >                 0x10000000 0x04000000>;    /* MEM2 64MB GDDR3 */
> >      };

This is, I think, because something marks all the address space from 0
to the end of MEM2 as RAM, and then cuts out a hole in the middle. I'm
not sure about the exact mechanism.

Unfortunately this hole has to be treated carefully because it contains
MMIO devices.

> Putting the same description in my mpc832x board DTS and doing a few hacks
> to get the WII functions called, I get the following:
> 
> [    0.000000] Top of RAM: 0x14000000, Total RAM: 0x5800000
> [    0.000000] Memory hole size: 232MB
> [    0.000000] Zone ranges:
> [    0.000000]   DMA      [mem 0x0000000000000000-0x0000000013ffffff]
> [    0.000000]   Normal   empty
> [    0.000000] Movable zone start for each node
> [    0.000000] Early memory node ranges
> [    0.000000]   node   0: [mem 0x0000000000000000-0x00000000017fffff]
> [    0.000000]   node   0: [mem 0x0000000010000000-0x0000000013ffffff]
> [    0.000000] Initmem setup node 0 [mem
> 0x0000000000000000-0x0000000013ffffff]
> [    0.000000] On node 0 totalpages: 22528
> [    0.000000]   DMA zone: 640 pages used for memmap
> [    0.000000]   DMA zone: 0 pages reserved
> [    0.000000]   DMA zone: 22528 pages, LIFO batch:3
> [    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
> [    0.000000] pcpu-alloc: [0] 0
> [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 21888
> [    0.000000] Kernel command line: loglevel=7
> ip=192.168.2.5:192.168.2.2::255.0
> [    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536
> bytes)
> [    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
> [    0.000000] Memory: 77060K/90112K available (6548K kernel code, 1156K
> rwdata,
> [    0.000000] Kernel virtual memory layout:
> [    0.000000]   * 0xfffdf000..0xfffff000  : fixmap
> [    0.000000]   * 0xfdffd000..0xfe000000  : early ioremap
> [    0.000000]   * 0xd5000000..0xfdffd000  : vmalloc & ioremap
> 
> 
> 
> 
> root@vgoippro:~# cat /sys/kernel/debug/powerpc/block_address_translation
> ---[ Instruction Block Address Translation ]---
> 0: 0xc0000000-0xc0ffffff 0x00000000 Kernel EXEC coherent
> 1:         -
> 2: 0xc1000000-0xc17fffff 0x01000000 Kernel EXEC coherent
> 3:         -
> 4: 0xd0000000-0xd3ffffff 0x10000000 Kernel EXEC coherent
> 5:         -
> 6:         -
> 7:         -
> 
> ---[ Data Block Address Translation ]---
> 0: 0xc0000000-0xc0ffffff 0x00000000 Kernel RW coherent
> 1: 0xfffe0000-0xffffffff 0x0d000000 Kernel RW no cache guarded
> 2: 0xc1000000-0xc17fffff 0x01000000 Kernel RW coherent
> 3:         -
> 4: 0xd0000000-0xd3ffffff 0x10000000 Kernel RW coherent
> 5:         -
> 6:         -
> 7:         -
> 
> 
> Could you please provide the dmesg and
> /sys/kernel/debug/powerpc/block_address_translation from before this patch,
> so that we can compare and identify the differences if any ?

After applying the patch that adds this debugfs file and enabling
CONFIG_PPC_PTDUMP, I get this:

	# cat /sys/kernel/debug/powerpc/block_address_translation
	---[ Instruction Block Address Translation ]---
	0:         -
	1:         -
	2: 0xc0000000-0xc0ffffff 0x00000000 Kernel EXEC
	3: 0xc1000000-0xc17fffff 0x01000000 Kernel EXEC
	4: 0xd0000000-0xd1ffffff 0x10000000 Kernel EXEC
	5:         -
	6:         -
	7:         -

	---[ Data Block Address Translation ]---
	0:         -
	1: 0xfffe0000-0xffffffff 0x0d000000 Kernel RW no cache guarded
	2: 0xc0000000-0xc0ffffff 0x00000000 Kernel RW
	3: 0xc1000000-0xc17fffff 0x01000000 Kernel RW
	4: 0xd0000000-0xd1ffffff 0x10000000 Kernel RW
	5:         -
	6:         -
	7:         -

dmesg is attached.


I added some tracing to the setbat function:

diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index f6f575bae3bc..4da3dc54fe46 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -120,6 +120,9 @@ void __init setbat(int index, unsigned long virt, phys_addr_t phys,
 	struct ppc_bat *bat = BATS[index];
 	unsigned long flags = pgprot_val(prot);
 
+	pr_info("setbat(%u, %px, %px, %px, %lx)\n",
+			index, (void *)virt, (void *)phys, (void *)size, flags);
+
 	if ((flags & _PAGE_NO_CACHE) ||
 	    (cpu_has_feature(CPU_FTR_NEED_COHERENT) == 0))
 		flags &= ~_PAGE_COHERENT;


And here's what I got:

Before your patches (circa v4.20-rc5):
[    0.000000] setbat(2, c0000000, 00000000, 01000000, 591)
[    0.000000] setbat(3, c1000000, 01000000, 00800000, 591)
[    0.000000] setbat(4, d0000000, 10000000, 02000000, 591)

With patches 1-3:
[    0.000000] setbat(0, c0000000, 00000000, 01000000, 311)
[    0.000000] setbat(2, c1000000, 01000000, 00800000, 311)
[    0.000000] setbat(4, d0000000, 10000000, 02000000, 791)

According to arch/powerpc/include/asm/book3s/32/hash.h,
 - 0x591 = _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | _PAGE_PRESENT
 - 0x311 = _PAGE_EXEC | _PAGE_ACCESSED | _PAGE_COHERENT | _PAGE_PRESENT
 - 0x791 = _PAGE_RW | _PAGE_EXEC | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | _PAGE_PRESENT

Changing the flags back to 0x591 in setbat doesn't result in a booting
system.


> > > I've tested at patch 1, 2, 3, 4, and 13, so I don't know if it works
> > > somewhere in the middle, but probably not.

(I get the same results if I also merge powerpc/next, btw)


I hope this helps somewhat,
  Jonathan Neuschäfer

[-- Attachment #1.2: wii-dmesg.txt --]
[-- Type: text/plain, Size: 10334 bytes --]

[    0.000000] printk: bootconsole [udbg0] enabled
[    0.000000] Total memory = 319MB; using 1024kB for hash table (at (ptrval))
[    0.000000] Linux version 4.20.0-rc5-wii-00021-g15eb67569a3d (jn@longitude) (gcc version 8.2.0 (Debian 8.2.0-9)) #1337 PREEMPT Sun Dec 16 02:37:19 CET 2018
[    0.000000] Using wii machine description
[    0.000000] -----------------------------------------------------
[    0.000000] Hash_size         = 0x100000
[    0.000000] phys_mem_size     = 0x5700000
[    0.000000] dcache_bsize      = 0x20
[    0.000000] icache_bsize      = 0x20
[    0.000000] cpu_features      = 0x000000000401a008
[    0.000000]   possible        = 0x000000002f7ff049
[    0.000000]   always          = 0x0000000000000000
[    0.000000] cpu_user_features = 0x8c000001 0x00000000
[    0.000000] mmu_features      = 0x00010001
[    0.000000] Hash              = 0x(ptrval)
[    0.000000] Hash_mask         = 0x3fff
[    0.000000] -----------------------------------------------------
[    0.000000] wii: hw_ctrl at 0x0d800100 mapped to 0x(ptrval)
[    0.000000] wii: hw_gpio at 0x0d8000c0 mapped to 0x(ptrval)
[    0.000000] Top of RAM: 0x13f00000, Total RAM: 0x5700000
[    0.000000] Memory hole size: 232MB
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x0000000000000000-0x0000000013efffff]
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x00000000017fffff]
[    0.000000]   node   0: [mem 0x0000000010000000-0x0000000013efffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000013efffff]
[    0.000000] On node 0 totalpages: 22272
[    0.000000]   DMA zone: 638 pages used for memmap
[    0.000000]   DMA zone: 0 pages reserved
[    0.000000]   DMA zone: 22272 pages, LIFO batch:3
[    0.000000] random: get_random_u32 called from start_kernel+0x84/0x438 with crng_init=0
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 21634
[    0.000000] Kernel command line: root=/dev/mmcblk0p2 rootwait console=usbgecko1
[    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Memory: 73016K/89088K available (7084K kernel code, 512K rwdata, 1796K rodata, 2724K init, 158K bss, 16072K reserved, 0K cma-reserved)
[    0.000000] Kernel virtual memory layout:
[    0.000000]   * 0xfffdf000..0xfffff000  : fixmap
[    0.000000]   * 0xfde00000..0xfe000000  : consistent mem
[    0.000000]   * 0xfddfe000..0xfde00000  : early ioremap
[    0.000000]   * 0xd4000000..0xfddfe000  : vmalloc & ioremap
[    0.000000] rcu: Preemptible hierarchical RCU implementation.
[    0.000000]  Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.000000] NR_IRQS: 512, nr_irqs: 512, preallocated irqs: 16
[    0.000000] flipper-pic: controller at 0x0c003000 mapped to 0x(ptrval)
[    0.000000] hlwd-pic: controller at 0x0d800030 mapped to 0x(ptrval)
[    0.000000] time_init: decrementer frequency = 60.750000 MHz
[    0.000000] time_init: processor frequency   = 729.000000 MHz
[    0.000012] clocksource: timebase: mask: 0xffffffffffffffff max_cycles: 0x1c0588ffb6, max_idle_ns: 881590404504 ns
[    0.004906] clocksource: timebase mult[83afef2] shift[23] registered
[    0.007920] clockevent: decrementer mult[f8d4fdf] shift[32] cpu[0]
[    0.011235] Console: colour dummy device 80x25
[    0.013381] pid_max: default: 32768 minimum: 301
[    0.015704] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.018862] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.023818] rcu: Hierarchical SRCU implementation.
[    0.026863] devtmpfs: initialized
[    0.057205] DMA-API: preallocated 65536 debug entries
[    0.059600] DMA-API: debugging enabled by kernel config
[    0.062146] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.066813] futex hash table entries: 256 (order: 0, 7168 bytes)
[    0.070472] NET: Registered protocol family 16
[    0.074531] exi: Nintendo GameCube/Wii EXternal Interface (EXI) driver - version 4.0i
[    0.079457] exi: about to add [exi0:0] id=0xfffffffe (external card)
[    0.082855] exi: add completed
[    0.084329] exi: about to add [exi0:1] id=0xfffff308 Wii Mask ROM/RTC/SRAM/UART
[    0.088140] exi: add completed
[    0.129762] SCSI subsystem initialized
[    0.131853] Advanced Linux Sound Architecture Driver Initialized.
[    0.138423] Bluetooth: Core ver 2.22
[    0.140835] NET: Registered protocol family 31
[    0.142944] Bluetooth: HCI device and connection manager initialized
[    0.146378] Bluetooth: HCI socket layer initialized
[    0.148693] Bluetooth: L2CAP socket layer initialized
[    0.151303] Bluetooth: SCO socket layer initialized
[    0.153707] clocksource: Switched to clocksource timebase
[    0.236624] NET: Registered protocol family 2
[    0.239818] tcp_listen_portaddr_hash hash table entries: 256 (order: 0, 6144 bytes)
[    0.243850] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.247389] TCP bind hash table entries: 1024 (order: 2, 20480 bytes)
[    0.250658] TCP: Hash tables configured (established 1024 bind 1024)
[    0.253850] UDP hash table entries: 256 (order: 1, 12288 bytes)
[    0.256758] UDP-Lite hash table entries: 256 (order: 1, 12288 bytes)
[    0.260147] NET: Registered protocol family 1
[    0.262867] RPC: Registered named UNIX socket transport module.
[    0.265675] RPC: Registered udp transport module.
[    0.267974] RPC: Registered tcp transport module.
[    0.270219] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.584441] Initialise system trusted keyrings
[    0.588214] workingset: timestamp_bits=30 max_order=15 bucket_order=0
[    0.682925] Key type asymmetric registered
[    0.684871] Asymmetric key parser 'x509' registered
[    0.687476] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
[    0.691178] io scheduler noop registered
[    0.693039] io scheduler deadline registered
[    0.695278] io scheduler cfq registered (default)
[    0.697511] io scheduler mq-deadline registered
[    0.699746] io scheduler kyber registered
[    0.755731] usbgecko: Console and TTY driver for the USB Gecko adapter - version 0.1i
[    0.760106] usbgecko: USB Gecko detected in memcard slot-A
[    1.341534] printk: console [usbgecko0] enabled
[    1.346940] Generic non-volatile memory driver v1.1
[    1.354626] brd: module loaded
[    1.372181] loop: module loaded
[    1.376667] Broadcom 43xx driver loaded [ Features: NS ]
[    1.383138] i2c /dev entries driver
[    1.388232] sdhci: Secure Digital Host Controller Interface driver
[    1.395102] sdhci: Copyright(c) Pierre Ossman
[    1.399557] sdhci-pltfm: SDHCI platform and OF driver helper
[    1.405551] mmc0 bounce up to 128 segments into one, max segment size 65536 bytes
[    1.437737] mmc0: SDHCI controller on d070000.sd [d070000.sd] using DMA
[    1.444910] mmc1 bounce up to 128 segments into one, max segment size 65536 bytes
[    1.477741] mmc1: SDHCI controller on d080000.sdio [d080000.sdio] using DMA
[    1.488556] NET: Registered protocol family 17
[    1.500457] Bluetooth: RFCOMM socket layer initialized
[    1.506001] Bluetooth: RFCOMM ver 1.11
[    1.510150] mmc0: new high speed SDHC card at address 1234
[    1.515730] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[    1.523394] mmcblk0: mmc0:1234 SA32G 28.9 GiB
[    1.527978] Bluetooth: BNEP filters: multicast
[    1.533692] Bluetooth: BNEP socket layer initialized
[    1.539240] Bluetooth: HIDP (Human Interface Emulation) ver 1.2
[    1.545434]  mmcblk0: p1
[    1.548923] Bluetooth: HIDP socket layer initialized
[    1.555729] drmem: No dynamic reconfiguration memory found
[    1.563332] Loading compiled-in X.509 certificates
[    1.568179] mmc1: queuing unknown CIS tuple 0x80 (2 bytes)
[    1.575175] input: gpio-keys as /devices/platform/gpio-keys/input/input0
[    1.583075] hctosys: unable to open rtc device (rtc0)
[    1.588566] mmc1: queuing unknown CIS tuple 0x80 (5 bytes)
[    1.594391] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[    1.603328] mmc1: queuing unknown CIS tuple 0x80 (2 bytes)
[    1.614717] mmc1: queuing unknown CIS tuple 0x80 (5 bytes)
[    1.624477] random: fast init done
[    1.632755] mmc1: queuing unknown CIS tuple 0x80 (10 bytes)
[    1.643310] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[    1.650089] mmc1: queuing unknown CIS tuple 0x80 (2 bytes)
[    1.655619] ALSA device list:
[    1.658623]   No soundcards found.
[    1.662253] mmc1: queuing unknown CIS tuple 0x80 (2 bytes)
[    1.674115] mmc1: queuing unknown CIS tuple 0x80 (5 bytes)
[    1.680759] Freeing unused kernel memory: 2724K
[    1.685600] mmc1: queuing unknown CIS tuple 0x80 (4 bytes)
[    1.691121] This architecture does not have kernel memory protection.
[    1.697611] mmc1: new SDIO card at address 0001
[    1.702178] Run /init as init process
[    1.706477] b43-sdio mmc1:0001:1: Chip ID 14e4:4318
[    1.716390] ssb: Found chip with id 0x4710, rev 0x00 and package 0x00
[    1.736283] ssb: WARNING: Multiple ChipCommon found
[    1.750060] b43-phy0: Broadcom 4710 WLAN found (core revision 9)
[    1.768026] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
[    1.785099] cfg80211: failed to load regulatory.db
[    1.794322] b43-phy0: Found PHY: Analog 3, Type 2 (G), Revision 7
[    1.806215] b43-phy0: Found Radio: Manuf 0x17F, ID 0x2050, Revision 8, Version 0
[    1.878936] b43-sdio mmc1:0001:1: Sonics Silicon Backplane found on SDIO device mmc1:0001:1
[    1.907732] udevd[615]: starting version 3.2.5
[    1.921820] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
[    1.937066] random: udevd: uninitialized urandom read (16 bytes read)
[    1.945644] random: udevd: uninitialized urandom read (16 bytes read)
[    1.952679] random: udevd: uninitialized urandom read (16 bytes read)
[    1.974388] udevd[616]: starting eudev-3.2.5
[    3.055809] random: dd: uninitialized urandom read (512 bytes read)

[-- Attachment #1.3: wii-conf --]
[-- Type: text/plain, Size: 3064 bytes --]

CONFIG_LOCALVERSION="-wii"
CONFIG_SYSVIPC=y
CONFIG_PREEMPT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="/home/jn/dev/linux/gc-linux/buildroot/images/rootfs.cpio"
CONFIG_EXPERT=y
# CONFIG_ELF_CORE is not set
CONFIG_PERF_EVENTS=y
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_SLAB=y
# CONFIG_PPC_CHRP is not set
# CONFIG_PPC_PMAC is not set
CONFIG_EMBEDDED6xx=y
CONFIG_WII=y
# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
CONFIG_KEXEC=y
# CONFIG_SECCOMP is not set
CONFIG_ADVANCED_OPTIONS=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_BINFMT_MISC=m
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_RARP=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set
CONFIG_BT=y
CONFIG_BT_RFCOMM=y
CONFIG_BT_BNEP=y
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_HIDP=y
CONFIG_CFG80211=y
CONFIG_MAC80211=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
# CONFIG_STANDALONE is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=2
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_NETDEVICES=y
# CONFIG_ETHERNET is not set
CONFIG_B43=y
CONFIG_B43_BUSES_SSB=y
CONFIG_B43_SDIO=y
# CONFIG_B43_PHY_LP is not set
CONFIG_B43_DEBUG=y
CONFIG_INPUT_FF_MEMLESS=m
CONFIG_INPUT_JOYDEV=y
CONFIG_INPUT_EVDEV=y
# CONFIG_KEYBOARD_ATKBD is not set
CONFIG_KEYBOARD_GPIO=y
# CONFIG_MOUSE_PS2 is not set
CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
# CONFIG_SERIO_I8042 is not set
# CONFIG_SERIO_SERPORT is not set
CONFIG_LEGACY_PTY_COUNT=64
CONFIG_SERIAL_USBGECKO=y
# CONFIG_HW_RANDOM is not set
CONFIG_NVRAM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_GPIO=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_HLWD=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_GPIO=y
# CONFIG_HWMON is not set
CONFIG_FB=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
# CONFIG_SND_VERBOSE_PROCFS is not set
CONFIG_SND_SEQUENCER=y
CONFIG_SND_SEQUENCER_OSS=y
CONFIG_HID_APPLE=m
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_OF_HLWD=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_GENERIC=y
CONFIG_EXT2_FS=y
CONFIG_EXT4_FS=y
CONFIG_FUSE_FS=m
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_PROC_KCORE=y
# CONFIG_PROC_PAGE_MONITOR is not set
CONFIG_TMPFS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_CIFS=m
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_CRYPTO_HW is not set
CONFIG_CRC_CCITT=y
CONFIG_PRINTK_TIME=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_LATENCYTOP=y
CONFIG_SCHED_TRACER=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_DMA_API_DEBUG=y
CONFIG_PPC_EARLY_DEBUG=y
CONFIG_PPC_PTDUMP=y

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-12-17  1:28         ` Jonathan Neuschäfer
@ 2018-12-17  9:29           ` Christophe Leroy
  2018-12-18  3:05             ` Jonathan Neuschäfer
  0 siblings, 1 reply; 27+ messages in thread
From: Christophe Leroy @ 2018-12-17  9:29 UTC (permalink / raw)
  To: Jonathan Neuschäfer; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel



Le 17/12/2018 à 02:28, Jonathan Neuschäfer a écrit :
> Hi, thanks for your reply.
> 
> On Thu, Dec 13, 2018 at 03:51:32PM +0100, Christophe Leroy wrote:
>> Hi Again,
>>
>> Le 13/12/2018 à 13:16, Christophe Leroy a écrit :
> [...]
>>> Can you tell/provide the .config and dts used ?
> 
> I'm using wii.dts and almost the wii_defconfig from my tree (save-
> defconfig result is attached), which is 4.20-rc5 plus a few patches:
> 
>    https://github.com/neuschaefer/linux wii-4.20-rc5        (w/o your patches)
>    https://github.com/neuschaefer/linux wii-4.20-rc5-ppcbat (w/ your patches 1-3)
> 
>>> You seem to have 319MB RAM wherease arch/powerpc/boot/dts/wii.dts only
>>> has 88MB Memory:
>>>
>>>       memory {
>>>           device_type = "memory";
>>>           reg = <0x00000000 0x01800000    /* MEM1 24MB 1T-SRAM */
>>>                  0x10000000 0x04000000>;    /* MEM2 64MB GDDR3 */
>>>       };
> 
> This is, I think, because something marks all the address space from 0
> to the end of MEM2 as RAM, and then cuts out a hole in the middle. I'm
> not sure about the exact mechanism.
> 
> Unfortunately this hole has to be treated carefully because it contains
> MMIO devices.
> 
>> Putting the same description in my mpc832x board DTS and doing a few hacks
>> to get the WII functions called, I get the following:
>>
>> [    0.000000] Top of RAM: 0x14000000, Total RAM: 0x5800000
>> [    0.000000] Memory hole size: 232MB
>> [    0.000000] Zone ranges:
>> [    0.000000]   DMA      [mem 0x0000000000000000-0x0000000013ffffff]
>> [    0.000000]   Normal   empty
>> [    0.000000] Movable zone start for each node
>> [    0.000000] Early memory node ranges
>> [    0.000000]   node   0: [mem 0x0000000000000000-0x00000000017fffff]
>> [    0.000000]   node   0: [mem 0x0000000010000000-0x0000000013ffffff]
>> [    0.000000] Initmem setup node 0 [mem
>> 0x0000000000000000-0x0000000013ffffff]
>> [    0.000000] On node 0 totalpages: 22528
>> [    0.000000]   DMA zone: 640 pages used for memmap
>> [    0.000000]   DMA zone: 0 pages reserved
>> [    0.000000]   DMA zone: 22528 pages, LIFO batch:3
>> [    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
>> [    0.000000] pcpu-alloc: [0] 0
>> [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 21888
>> [    0.000000] Kernel command line: loglevel=7
>> ip=192.168.2.5:192.168.2.2::255.0
>> [    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536
>> bytes)
>> [    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
>> [    0.000000] Memory: 77060K/90112K available (6548K kernel code, 1156K
>> rwdata,
>> [    0.000000] Kernel virtual memory layout:
>> [    0.000000]   * 0xfffdf000..0xfffff000  : fixmap
>> [    0.000000]   * 0xfdffd000..0xfe000000  : early ioremap
>> [    0.000000]   * 0xd5000000..0xfdffd000  : vmalloc & ioremap
>>
>>
>>
>>
>> root@vgoippro:~# cat /sys/kernel/debug/powerpc/block_address_translation
>> ---[ Instruction Block Address Translation ]---
>> 0: 0xc0000000-0xc0ffffff 0x00000000 Kernel EXEC coherent
>> 1:         -
>> 2: 0xc1000000-0xc17fffff 0x01000000 Kernel EXEC coherent
>> 3:         -
>> 4: 0xd0000000-0xd3ffffff 0x10000000 Kernel EXEC coherent
>> 5:         -
>> 6:         -
>> 7:         -
>>
>> ---[ Data Block Address Translation ]---
>> 0: 0xc0000000-0xc0ffffff 0x00000000 Kernel RW coherent
>> 1: 0xfffe0000-0xffffffff 0x0d000000 Kernel RW no cache guarded
>> 2: 0xc1000000-0xc17fffff 0x01000000 Kernel RW coherent
>> 3:         -
>> 4: 0xd0000000-0xd3ffffff 0x10000000 Kernel RW coherent
>> 5:         -
>> 6:         -
>> 7:         -
>>
>>
>> Could you please provide the dmesg and
>> /sys/kernel/debug/powerpc/block_address_translation from before this patch,
>> so that we can compare and identify the differences if any ?
> 
> After applying the patch that adds this debugfs file and enabling
> CONFIG_PPC_PTDUMP, I get this:
> 
> 	# cat /sys/kernel/debug/powerpc/block_address_translation
> 	---[ Instruction Block Address Translation ]---
> 	0:         -
> 	1:         -
> 	2: 0xc0000000-0xc0ffffff 0x00000000 Kernel EXEC
> 	3: 0xc1000000-0xc17fffff 0x01000000 Kernel EXEC
> 	4: 0xd0000000-0xd1ffffff 0x10000000 Kernel EXEC
> 	5:         -
> 	6:         -
> 	7:         -
> 
> 	---[ Data Block Address Translation ]---
> 	0:         -
> 	1: 0xfffe0000-0xffffffff 0x0d000000 Kernel RW no cache guarded
> 	2: 0xc0000000-0xc0ffffff 0x00000000 Kernel RW
> 	3: 0xc1000000-0xc17fffff 0x01000000 Kernel RW
> 	4: 0xd0000000-0xd1ffffff 0x10000000 Kernel RW
> 	5:         -
> 	6:         -
> 	7:         -
> 
> dmesg is attached.
> 
> 
> I added some tracing to the setbat function:
> 
> diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
> index f6f575bae3bc..4da3dc54fe46 100644
> --- a/arch/powerpc/mm/ppc_mmu_32.c
> +++ b/arch/powerpc/mm/ppc_mmu_32.c
> @@ -120,6 +120,9 @@ void __init setbat(int index, unsigned long virt, phys_addr_t phys,
>   	struct ppc_bat *bat = BATS[index];
>   	unsigned long flags = pgprot_val(prot);
>   
> +	pr_info("setbat(%u, %px, %px, %px, %lx)\n",
> +			index, (void *)virt, (void *)phys, (void *)size, flags);
> +
>   	if ((flags & _PAGE_NO_CACHE) ||
>   	    (cpu_has_feature(CPU_FTR_NEED_COHERENT) == 0))
>   		flags &= ~_PAGE_COHERENT;
> 
> 
> And here's what I got:
> 
> Before your patches (circa v4.20-rc5):
> [    0.000000] setbat(2, c0000000, 00000000, 01000000, 591)
> [    0.000000] setbat(3, c1000000, 01000000, 00800000, 591)
> [    0.000000] setbat(4, d0000000, 10000000, 02000000, 591)

Ok, I have not tested against raw v4.20-rc5. I always powerpc/merge 
branch as the reference. Maybe I should try that.

> 
> With patches 1-3:
> [    0.000000] setbat(0, c0000000, 00000000, 01000000, 311)
> [    0.000000] setbat(2, c1000000, 01000000, 00800000, 311)
> [    0.000000] setbat(4, d0000000, 10000000, 02000000, 791)

What we see is that BAT0 is not used in the origin. I have always 
wondered the reason, maybe there is something odd behind and BAT0 shall 
no ne used.

Could you try and modify find_free_bat() so that it starts at b = 1 
instead of b = 0 ?

> 
> According to arch/powerpc/include/asm/book3s/32/hash.h,
>   - 0x591 = _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | _PAGE_PRESENT
>   - 0x311 = _PAGE_EXEC | _PAGE_ACCESSED | _PAGE_COHERENT | _PAGE_PRESENT
>   - 0x791 = _PAGE_RW | _PAGE_EXEC | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | _PAGE_PRESENT
> 

Yes, patch 1 added _PAGE_EXEC which explains this 0x200.
Do you confirm it still works well with only patch 1 ?

And patch 3 uses PAGE_KERNEL_TEXT instead of PAGE_KERNEL_X, hence the 
lack of _PAGE_RW, which should not be necessary.



> Changing the flags back to 0x591 in setbat doesn't result in a booting
> system.
> 
> 
>>>> I've tested at patch 1, 2, 3, 4, and 13, so I don't know if it works
>>>> somewhere in the middle, but probably not.
> 
> (I get the same results if I also merge powerpc/next, btw)

Ok, then no need for me to test with raw 4.20 rc 5.

Christophe

> 
> 
> I hope this helps somewhat,
>    Jonathan Neuschäfer
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-12-17  9:29           ` Christophe Leroy
@ 2018-12-18  3:05             ` Jonathan Neuschäfer
  2018-12-18  9:18               ` Christophe Leroy
  0 siblings, 1 reply; 27+ messages in thread
From: Jonathan Neuschäfer @ 2018-12-18  3:05 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Jonathan Neuschäfer, linuxppc-dev, Paul Mackerras, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1146 bytes --]

On Mon, Dec 17, 2018 at 10:29:18AM +0100, Christophe Leroy wrote:
> > With patches 1-3:
> > [    0.000000] setbat(0, c0000000, 00000000, 01000000, 311)
> > [    0.000000] setbat(2, c1000000, 01000000, 00800000, 311)
> > [    0.000000] setbat(4, d0000000, 10000000, 02000000, 791)
> 
> What we see is that BAT0 is not used in the origin. I have always wondered
> the reason, maybe there is something odd behind and BAT0 shall no ne used.
> 
> Could you try and modify find_free_bat() so that it starts at b = 1 instead
> of b = 0 ?

In this case, setbat is called with index 2, 3, and 4, but the Wii still
doesn't boot.

> > According to arch/powerpc/include/asm/book3s/32/hash.h,
> >   - 0x591 = _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | _PAGE_PRESENT
> >   - 0x311 = _PAGE_EXEC | _PAGE_ACCESSED | _PAGE_COHERENT | _PAGE_PRESENT
> >   - 0x791 = _PAGE_RW | _PAGE_EXEC | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | _PAGE_PRESENT
> > 
> 
> Yes, patch 1 added _PAGE_EXEC which explains this 0x200.
> Do you confirm it still works well with only patch 1 ?

Patch 1 alone boots to userspace.


Jonathan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-12-18  3:05             ` Jonathan Neuschäfer
@ 2018-12-18  9:18               ` Christophe Leroy
  2018-12-18 14:07                 ` Jonathan Neuschäfer
  0 siblings, 1 reply; 27+ messages in thread
From: Christophe Leroy @ 2018-12-18  9:18 UTC (permalink / raw)
  To: Jonathan Neuschäfer; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel



On 12/18/2018 03:05 AM, Jonathan Neuschäfer wrote:
> On Mon, Dec 17, 2018 at 10:29:18AM +0100, Christophe Leroy wrote:
>>> With patches 1-3:
>>> [    0.000000] setbat(0, c0000000, 00000000, 01000000, 311)
>>> [    0.000000] setbat(2, c1000000, 01000000, 00800000, 311)
>>> [    0.000000] setbat(4, d0000000, 10000000, 02000000, 791)
>>
>> What we see is that BAT0 is not used in the origin. I have always wondered
>> the reason, maybe there is something odd behind and BAT0 shall no ne used.
>>
>> Could you try and modify find_free_bat() so that it starts at b = 1 instead
>> of b = 0 ?
> 
> In this case, setbat is called with index 2, 3, and 4, but the Wii still
> doesn't boot.
> 
>>> According to arch/powerpc/include/asm/book3s/32/hash.h,
>>>    - 0x591 = _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | _PAGE_PRESENT
>>>    - 0x311 = _PAGE_EXEC | _PAGE_ACCESSED | _PAGE_COHERENT | _PAGE_PRESENT
>>>    - 0x791 = _PAGE_RW | _PAGE_EXEC | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | _PAGE_PRESENT
>>>
>>
>> Yes, patch 1 added _PAGE_EXEC which explains this 0x200.
>> Do you confirm it still works well with only patch 1 ?
> 
> Patch 1 alone boots to userspace.
> 

Ok, thanks for testing.

The only difference I see then are the flags. Everything else is seems 
identical.

I know you tried already, but would you mind trying once more with the 
following change ?

diff --git b/arch/powerpc/mm/ppc_mmu_32.c a/arch/powerpc/mm/ppc_mmu_32.c
index 61c10ee00ba2..628fba266663 100644
--- b/arch/powerpc/mm/ppc_mmu_32.c
+++ a/arch/powerpc/mm/ppc_mmu_32.c
@@ -119,7 +119,7 @@ unsigned long __init mmu_mapin_ram(unsigned long 
base, unsigned long top)

  		if (size < 128 << 10)
  			break;
-		setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
+		setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
  		base += size;
  	}

I think we may have some code trying to modify the kernel text without 
using code patching functions.

Thanks,
Christophe


> 
> Jonathan
> 

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-12-18  9:18               ` Christophe Leroy
@ 2018-12-18 14:07                 ` Jonathan Neuschäfer
  2018-12-18 14:15                   ` Christophe Leroy
  0 siblings, 1 reply; 27+ messages in thread
From: Jonathan Neuschäfer @ 2018-12-18 14:07 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Jonathan Neuschäfer, linuxppc-dev, Paul Mackerras, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1416 bytes --]

On Tue, Dec 18, 2018 at 09:18:42AM +0000, Christophe Leroy wrote:
> The only difference I see then are the flags. Everything else is seems
> identical.
> 
> I know you tried already, but would you mind trying once more with the
> following change ?
> 
[...]
> -		setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
> +		setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);

Good call, with this workaround on top of patches 1-3, it boots again:

	# mount -t debugfs d /sys/kernel/debug
	# cat /sys/kernel/debug/powerpc/block_address_translation
	---[ Instruction Block Address Translation ]---
	0: 0xc0000000-0xc0ffffff 0x00000000 Kernel EXEC
	1:         -
	2: 0xc1000000-0xc17fffff 0x01000000 Kernel EXEC
	3:         -
	4: 0xd0000000-0xd1ffffff 0x10000000 Kernel EXEC
	5:         -
	6:         -
	7:         -

	---[ Data Block Address Translation ]---
	0: 0xc0000000-0xc0ffffff 0x00000000 Kernel RW
	1: 0xfffe0000-0xffffffff 0x0d000000 Kernel RW no cache guarded
	2: 0xc1000000-0xc17fffff 0x01000000 Kernel RW
	3:         -
	4: 0xd0000000-0xd1ffffff 0x10000000 Kernel RW
	5:         -
	6:         -
	7:         -

> I think we may have some code trying to modify the kernel text without using
> code patching functions.

Is there any faster way than to sprinkle some printks in setup_kernel
and try to find the guilty piece of code this way?


Jonathan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-12-18 14:07                 ` Jonathan Neuschäfer
@ 2018-12-18 14:15                   ` Christophe Leroy
  2018-12-18 14:55                     ` Christophe Leroy
  0 siblings, 1 reply; 27+ messages in thread
From: Christophe Leroy @ 2018-12-18 14:15 UTC (permalink / raw)
  To: Jonathan Neuschäfer; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel



Le 18/12/2018 à 15:07, Jonathan Neuschäfer a écrit :
> On Tue, Dec 18, 2018 at 09:18:42AM +0000, Christophe Leroy wrote:
>> The only difference I see then are the flags. Everything else is seems
>> identical.
>>
>> I know you tried already, but would you mind trying once more with the
>> following change ?
>>
> [...]
>> -		setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
>> +		setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
> 
> Good call, with this workaround on top of patches 1-3, it boots again:
> 
> 	# mount -t debugfs d /sys/kernel/debug
> 	# cat /sys/kernel/debug/powerpc/block_address_translation
> 	---[ Instruction Block Address Translation ]---
> 	0: 0xc0000000-0xc0ffffff 0x00000000 Kernel EXEC
> 	1:         -
> 	2: 0xc1000000-0xc17fffff 0x01000000 Kernel EXEC
> 	3:         -
> 	4: 0xd0000000-0xd1ffffff 0x10000000 Kernel EXEC
> 	5:         -
> 	6:         -
> 	7:         -
> 
> 	---[ Data Block Address Translation ]---
> 	0: 0xc0000000-0xc0ffffff 0x00000000 Kernel RW
> 	1: 0xfffe0000-0xffffffff 0x0d000000 Kernel RW no cache guarded
> 	2: 0xc1000000-0xc17fffff 0x01000000 Kernel RW
> 	3:         -
> 	4: 0xd0000000-0xd1ffffff 0x10000000 Kernel RW
> 	5:         -
> 	6:         -
> 	7:         -
> 
>> I think we may have some code trying to modify the kernel text without using
>> code patching functions.
> 
> Is there any faster way than to sprinkle some printks in setup_kernel
> and try to find the guilty piece of code this way?

Can you start with the serie 
https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=75072 ?

Christophe

> 
> 
> Jonathan
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-12-18 14:15                   ` Christophe Leroy
@ 2018-12-18 14:55                     ` Christophe Leroy
  2018-12-18 15:04                       ` Christophe Leroy
  0 siblings, 1 reply; 27+ messages in thread
From: Christophe Leroy @ 2018-12-18 14:55 UTC (permalink / raw)
  To: Jonathan Neuschäfer; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel



Le 18/12/2018 à 15:15, Christophe Leroy a écrit :
> 
> 
> Le 18/12/2018 à 15:07, Jonathan Neuschäfer a écrit :
>> On Tue, Dec 18, 2018 at 09:18:42AM +0000, Christophe Leroy wrote:
>>> The only difference I see then are the flags. Everything else is seems
>>> identical.
>>>
>>> I know you tried already, but would you mind trying once more with the
>>> following change ?
>>>
>> [...]
>>> -        setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
>>> +        setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
>>
>> Good call, with this workaround on top of patches 1-3, it boots again:
>>
>>     # mount -t debugfs d /sys/kernel/debug
>>     # cat /sys/kernel/debug/powerpc/block_address_translation
>>     ---[ Instruction Block Address Translation ]---
>>     0: 0xc0000000-0xc0ffffff 0x00000000 Kernel EXEC
>>     1:         -
>>     2: 0xc1000000-0xc17fffff 0x01000000 Kernel EXEC
>>     3:         -
>>     4: 0xd0000000-0xd1ffffff 0x10000000 Kernel EXEC
>>     5:         -
>>     6:         -
>>     7:         -
>>
>>     ---[ Data Block Address Translation ]---
>>     0: 0xc0000000-0xc0ffffff 0x00000000 Kernel RW
>>     1: 0xfffe0000-0xffffffff 0x0d000000 Kernel RW no cache guarded
>>     2: 0xc1000000-0xc17fffff 0x01000000 Kernel RW
>>     3:         -
>>     4: 0xd0000000-0xd1ffffff 0x10000000 Kernel RW
>>     5:         -
>>     6:         -
>>     7:         -
>>
>>> I think we may have some code trying to modify the kernel text 
>>> without using
>>> code patching functions.
>>
>> Is there any faster way than to sprinkle some printks in setup_kernel
>> and try to find the guilty piece of code this way?
> 
> Can you start with the serie 
> https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=75072 ?

Ok, the thing I was thinking about was the MMU_init_hw() but it is 
called before mapin_ram() so it should not be a problem. Not sure that 
serie improves anything at all here.

So there must be something else, pretty early (before the system is able 
to properly handle and display an Oops for write to RO area.)

Does anybody have an idea of what it can be ?

Christophe

> 
> Christophe
> 
>>
>>
>> Jonathan
>>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-12-18 14:55                     ` Christophe Leroy
@ 2018-12-18 15:04                       ` Christophe Leroy
  2018-12-18 17:04                         ` Jonathan Neuschäfer
  0 siblings, 1 reply; 27+ messages in thread
From: Christophe Leroy @ 2018-12-18 15:04 UTC (permalink / raw)
  To: Jonathan Neuschäfer; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel



Le 18/12/2018 à 15:55, Christophe Leroy a écrit :
> 
> 
> Le 18/12/2018 à 15:15, Christophe Leroy a écrit :
>>
>>
>> Le 18/12/2018 à 15:07, Jonathan Neuschäfer a écrit :
>>> On Tue, Dec 18, 2018 at 09:18:42AM +0000, Christophe Leroy wrote:
>>>> The only difference I see then are the flags. Everything else is seems
>>>> identical.
>>>>
>>>> I know you tried already, but would you mind trying once more with the
>>>> following change ?
>>>>
>>> [...]
>>>> -        setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
>>>> +        setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
>>>
>>> Good call, with this workaround on top of patches 1-3, it boots again:
>>>
>>>     # mount -t debugfs d /sys/kernel/debug
>>>     # cat /sys/kernel/debug/powerpc/block_address_translation
>>>     ---[ Instruction Block Address Translation ]---
>>>     0: 0xc0000000-0xc0ffffff 0x00000000 Kernel EXEC
>>>     1:         -
>>>     2: 0xc1000000-0xc17fffff 0x01000000 Kernel EXEC
>>>     3:         -
>>>     4: 0xd0000000-0xd1ffffff 0x10000000 Kernel EXEC
>>>     5:         -
>>>     6:         -
>>>     7:         -
>>>
>>>     ---[ Data Block Address Translation ]---
>>>     0: 0xc0000000-0xc0ffffff 0x00000000 Kernel RW
>>>     1: 0xfffe0000-0xffffffff 0x0d000000 Kernel RW no cache guarded
>>>     2: 0xc1000000-0xc17fffff 0x01000000 Kernel RW
>>>     3:         -
>>>     4: 0xd0000000-0xd1ffffff 0x10000000 Kernel RW
>>>     5:         -
>>>     6:         -
>>>     7:         -
>>>
>>>> I think we may have some code trying to modify the kernel text 
>>>> without using
>>>> code patching functions.
>>>
>>> Is there any faster way than to sprinkle some printks in setup_kernel
>>> and try to find the guilty piece of code this way?
>>
>> Can you start with the serie 
>> https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=75072 ?
> 
> Ok, the thing I was thinking about was the MMU_init_hw() but it is 
> called before mapin_ram() so it should not be a problem. Not sure that 
> serie improves anything at all here.
> 
> So there must be something else, pretty early (before the system is able 
> to properly handle and display an Oops for write to RO area.)
> 
> Does anybody have an idea of what it can be ?


Stupid of me. In fact at the time being, BATS cover both RO and RW data 
areas, so it can definitly not be mapped with PAGE_KERNEL_ROX.

In fact, as I have CONFIG_BDI_SWITCH in my setup, PAGE_KERNEL_TEXT is 
PAGE_KERNEL_X on my side. That's the reason why I missed it.

With this change being done to patch 3, does the overall serie works for 
you ?

Thanks
Christophe



> 
> Christophe
> 
>>
>> Christophe
>>
>>>
>>>
>>> Jonathan
>>>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-12-18 15:04                       ` Christophe Leroy
@ 2018-12-18 17:04                         ` Jonathan Neuschäfer
  2018-12-18 18:13                           ` Christophe Leroy
  0 siblings, 1 reply; 27+ messages in thread
From: Jonathan Neuschäfer @ 2018-12-18 17:04 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Jonathan Neuschäfer, linuxppc-dev, Paul Mackerras, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 523 bytes --]

On Tue, Dec 18, 2018 at 04:04:42PM +0100, Christophe Leroy wrote:
> Stupid of me. In fact at the time being, BATS cover both RO and RW data
> areas, so it can definitly not be mapped with PAGE_KERNEL_ROX.
> 
> In fact, as I have CONFIG_BDI_SWITCH in my setup, PAGE_KERNEL_TEXT is
> PAGE_KERNEL_X on my side. That's the reason why I missed it.
> 
> With this change being done to patch 3, does the overall serie works for you ?

Yes, with the PAGE_KERNEL_X change, the whole series boots on the Wii.


Jonathan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram()
  2018-12-18 17:04                         ` Jonathan Neuschäfer
@ 2018-12-18 18:13                           ` Christophe Leroy
  0 siblings, 0 replies; 27+ messages in thread
From: Christophe Leroy @ 2018-12-18 18:13 UTC (permalink / raw)
  To: Jonathan Neuschäfer; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel

Le 18/12/2018 à 18:04, Jonathan Neuschäfer a écrit :
> On Tue, Dec 18, 2018 at 04:04:42PM +0100, Christophe Leroy wrote:
>> Stupid of me. In fact at the time being, BATS cover both RO and RW data
>> areas, so it can definitly not be mapped with PAGE_KERNEL_ROX.
>>
>> In fact, as I have CONFIG_BDI_SWITCH in my setup, PAGE_KERNEL_TEXT is
>> PAGE_KERNEL_X on my side. That's the reason why I missed it.
>>
>> With this change being done to patch 3, does the overall serie works for you ?
> 
> Yes, with the PAGE_KERNEL_X change, the whole series boots on the Wii.

That's great, many thanks for testing.

Christophe

> 
> 
> Jonathan
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2018-12-18 18:13 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-29 19:00 [PATCH v1 00/13] powerpc/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 01/13] powerpc/mm: add exec protection on powerpc 603 Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 02/13] powerpc/mm/32: add base address to mmu_mapin_ram() Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 03/13] powerpc/mm/32s: rework mmu_mapin_ram() Christophe Leroy
2018-12-03 21:55   ` Jonathan Neuschäfer
2018-12-13 12:16     ` Christophe Leroy
2018-12-13 14:51       ` Christophe Leroy
2018-12-17  1:28         ` Jonathan Neuschäfer
2018-12-17  9:29           ` Christophe Leroy
2018-12-18  3:05             ` Jonathan Neuschäfer
2018-12-18  9:18               ` Christophe Leroy
2018-12-18 14:07                 ` Jonathan Neuschäfer
2018-12-18 14:15                   ` Christophe Leroy
2018-12-18 14:55                     ` Christophe Leroy
2018-12-18 15:04                       ` Christophe Leroy
2018-12-18 17:04                         ` Jonathan Neuschäfer
2018-12-18 18:13                           ` Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 04/13] powerpc/mm/32s: use generic mmu_mapin_ram() for all blocks Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 05/13] powerpc/wii: remove wii_mmu_mapin_mem2() Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 06/13] powerpc/mm/32s: use _PAGE_EXEC in setbat() Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 07/13] powerpc/mm/32s: add setibat() clearibat() and update_bats() Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 08/13] powerpc/32: add helper to write into segment registers Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 09/13] powerpc/mmu: add is_strict_kernel_rwx() helper Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 10/13] powerpc/kconfig: define PAGE_SHIFT inside Kconfig Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 11/13] powerpc/kconfig: define CONFIG_DATA_SHIFT and CONFIG_ETEXT_SHIFT Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 12/13] powerpc/mm/32s: Use BATs for STRICT_KERNEL_RWX Christophe Leroy
2018-11-29 19:00 ` [PATCH v1 13/13] powerpc/kconfig: make _etext and data areas alignment configurable on Book3s 32 Christophe Leroy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).