[PATCH v2 13/16] powerpc/64s: Move hash MMU code under a new Kconfig name

Christophe Leroy christophe.leroy at csgroup.eu
Thu Oct 21 16:43:10 AEDT 2021



Le 21/10/2021 à 05:54, Nicholas Piggin a écrit :
> Introduce a new option CONFIG_PPC_64S_HASH_MMU, and make 64s hash
> code depend on it.
> 
> Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
> ---
>   arch/powerpc/Kconfig                          |  2 +-
>   arch/powerpc/include/asm/book3s/64/mmu.h      | 19 +++++++++--
>   .../include/asm/book3s/64/tlbflush-hash.h     |  7 ++++
>   arch/powerpc/include/asm/book3s/pgtable.h     |  4 +++
>   arch/powerpc/include/asm/mmu.h                | 16 +++++++--
>   arch/powerpc/include/asm/mmu_context.h        |  2 ++
>   arch/powerpc/include/asm/paca.h               |  8 +++++
>   arch/powerpc/kernel/asm-offsets.c             |  2 ++
>   arch/powerpc/kernel/dt_cpu_ftrs.c             | 14 +++++---
>   arch/powerpc/kernel/entry_64.S                |  4 +--
>   arch/powerpc/kernel/exceptions-64s.S          | 16 +++++++++
>   arch/powerpc/kernel/mce.c                     |  2 +-
>   arch/powerpc/kernel/mce_power.c               | 10 ++++--
>   arch/powerpc/kernel/paca.c                    | 18 ++++------
>   arch/powerpc/kernel/process.c                 | 13 +++----
>   arch/powerpc/kernel/prom.c                    |  2 ++
>   arch/powerpc/kernel/setup_64.c                |  5 +++
>   arch/powerpc/kexec/core_64.c                  |  4 +--
>   arch/powerpc/kexec/ranges.c                   |  4 +++
>   arch/powerpc/mm/book3s64/Makefile             | 15 ++++----
>   arch/powerpc/mm/book3s64/hugetlbpage.c        |  2 ++
>   arch/powerpc/mm/book3s64/mmu_context.c        | 34 +++++++++++++++----
>   arch/powerpc/mm/book3s64/radix_pgtable.c      |  4 +++
>   arch/powerpc/mm/copro_fault.c                 |  2 ++
>   arch/powerpc/mm/ioremap.c                     | 13 ++++---
>   arch/powerpc/mm/pgtable.c                     | 10 ++++--
>   arch/powerpc/mm/ptdump/Makefile               |  2 +-
>   arch/powerpc/platforms/Kconfig.cputype        |  4 +++
>   arch/powerpc/platforms/powernv/idle.c         |  2 ++
>   arch/powerpc/platforms/powernv/setup.c        |  2 ++
>   arch/powerpc/platforms/pseries/lpar.c         | 11 ++++--
>   arch/powerpc/platforms/pseries/lparcfg.c      |  2 +-
>   arch/powerpc/platforms/pseries/mobility.c     |  6 ++++
>   arch/powerpc/platforms/pseries/ras.c          |  2 ++
>   arch/powerpc/platforms/pseries/reconfig.c     |  2 ++
>   arch/powerpc/platforms/pseries/setup.c        |  6 ++--
>   arch/powerpc/xmon/xmon.c                      |  8 +++--
>   drivers/misc/lkdtm/Makefile                   |  2 +-
>   drivers/misc/lkdtm/core.c                     |  2 +-
>   39 files changed, 219 insertions(+), 64 deletions(-)

I'm still unconfortable with the quantity of files impacted in that commit.

> 

> diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h
> index c02f42d1031e..d94ebae386b6 100644
> --- a/arch/powerpc/include/asm/book3s/64/mmu.h
> +++ b/arch/powerpc/include/asm/book3s/64/mmu.h

> @@ -193,8 +198,15 @@ static inline struct subpage_prot_table *mm_ctx_subpage_prot(mm_context_t *ctx)
>   extern int mmu_linear_psize;
>   extern int mmu_virtual_psize;
>   extern int mmu_vmalloc_psize;
> -extern int mmu_vmemmap_psize;
>   extern int mmu_io_psize;
> +#else /* CONFIG_PPC_64S_HASH_MMU */
> +#ifdef CONFIG_PPC_64K_PAGES

Avoid nested #ifdefs and do

#elif defined(CONFIG_PPC_64K_PAGES)

> +#define mmu_virtual_psize MMU_PAGE_64K
> +#else
> +#define mmu_virtual_psize MMU_PAGE_4K
> +#endif
> +#endif
> +extern int mmu_vmemmap_psize;
>   
>   /* MMU initialization */
>   void mmu_early_init_devtree(void);
> @@ -233,7 +245,8 @@ static inline void setup_initial_memory_limit(phys_addr_t first_memblock_base,
>   	 * know which translations we will pick. Hence go with hash
>   	 * restrictions.
>   	 */
> -	return hash__setup_initial_memory_limit(first_memblock_base,
> +	if (!radix_enabled())
> +		return hash__setup_initial_memory_limit(first_memblock_base,
>   					   first_memblock_size);
>   }
>   
> @@ -255,6 +268,7 @@ static inline void radix_init_pseries(void) { }
>   void cleanup_cpu_mmu_context(void);
>   #endif
>   
> +#ifdef CONFIG_PPC_64S_HASH_MMU
>   static inline int get_user_context(mm_context_t *ctx, unsigned long ea)
>   {
>   	int index = ea >> MAX_EA_BITS_PER_CONTEXT;
> @@ -274,6 +288,7 @@ static inline unsigned long get_user_vsid(mm_context_t *ctx,
>   
>   	return get_vsid(context, ea, ssize);
>   }
> +#endif
>   
>   #endif /* __ASSEMBLY__ */
>   #endif /* _ASM_POWERPC_BOOK3S_64_MMU_H_ */
> diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
> index 3b95769739c7..06f4bd09eecf 100644
> --- a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
> +++ b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
> @@ -112,8 +112,15 @@ static inline void hash__flush_tlb_kernel_range(unsigned long start,
>   
>   struct mmu_gather;
>   extern void hash__tlb_flush(struct mmu_gather *tlb);
> +extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd,

'extern' is superfluous.

> +				unsigned long addr);
> +
> +#ifdef CONFIG_PPC_64S_HASH_MMU
>   /* Private function for use by PCI IO mapping code */
>   extern void __flush_hash_table_range(unsigned long start, unsigned long end);
>   extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd,
>   				unsigned long addr);
> +#else
> +static inline void __flush_hash_table_range(unsigned long start, unsigned long end) { }
> +#endif
>   #endif /*  _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H */

> diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
> index 8abe8e42e045..226417f26145 100644
> --- a/arch/powerpc/include/asm/mmu.h
> +++ b/arch/powerpc/include/asm/mmu.h
> @@ -157,7 +157,7 @@ DECLARE_PER_CPU(int, next_tlbcam_idx);
>   
>   enum {
>   	MMU_FTRS_POSSIBLE =
> -#if defined(CONFIG_PPC_BOOK3S_64) || defined(CONFIG_PPC_BOOK3S_604)
> +#if defined(CONFIG_PPC_BOOK3S_604)
>   		MMU_FTR_HPTE_TABLE |
>   #endif
>   #ifdef CONFIG_PPC_8xx
> @@ -184,15 +184,18 @@ enum {
>   		MMU_FTR_USE_TLBRSRV | MMU_FTR_USE_PAIRED_MAS |
>   #endif
>   #ifdef CONFIG_PPC_BOOK3S_64
> +		MMU_FTR_KERNEL_RO |
> +#ifdef CONFIG_PPC_64S_HASH_MMU
>   		MMU_FTR_NO_SLBIE_B | MMU_FTR_16M_PAGE | MMU_FTR_TLBIEL |
>   		MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_CI_LARGE_PAGE |
>   		MMU_FTR_1T_SEGMENT | MMU_FTR_TLBIE_CROP_VA |
> -		MMU_FTR_KERNEL_RO | MMU_FTR_68_BIT_VA |
> +		MMU_FTR_68_BIT_VA | MMU_FTR_HPTE_TABLE |
>   #endif
>   #ifdef CONFIG_PPC_RADIX_MMU
>   		MMU_FTR_TYPE_RADIX |
>   		MMU_FTR_GTSE |
>   #endif /* CONFIG_PPC_RADIX_MMU */
> +#endif
>   #ifdef CONFIG_PPC_KUAP
>   	MMU_FTR_BOOK3S_KUAP |
>   #endif /* CONFIG_PPC_KUAP */
> @@ -223,6 +226,13 @@ enum {
>   #ifdef CONFIG_E500
>   #define MMU_FTRS_ALWAYS		MMU_FTR_TYPE_FSL_E
>   #endif
> +#ifdef CONFIG_PPC_BOOK3S_64

No need of this CONFIG_PPC_BOOK3S_64 ifdef, it is necessarily defined if 
either CONFIG_PPC_RADIX_MMU or CONFIG_PPC_64S_HASH_MMU is defined


> +#if defined(CONFIG_PPC_RADIX_MMU) && !defined(CONFIG_PPC_64S_HASH_MMU)
> +#define MMU_FTRS_ALWAYS		MMU_FTR_TYPE_RADIX
> +#elif !defined(CONFIG_PPC_RADIX_MMU) && defined(CONFIG_PPC_64S_HASH_MMU)
> +#define MMU_FTRS_ALWAYS		MMU_FTR_HPTE_TABLE
> +#endif
> +#endif
>   
>   #ifndef MMU_FTRS_ALWAYS
>   #define MMU_FTRS_ALWAYS		0

> diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
> index 046c99e31d01..65b695e9401e 100644
> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -1369,11 +1369,15 @@ EXC_COMMON_BEGIN(data_access_common)
>   	addi	r3,r1,STACK_FRAME_OVERHEAD
>   	andis.	r0,r4,DSISR_DABRMATCH at h
>   	bne-	1f
> +#ifdef CONFIG_PPC_64S_HASH_MMU
>   BEGIN_MMU_FTR_SECTION
>   	bl	do_hash_fault
>   MMU_FTR_SECTION_ELSE
>   	bl	do_page_fault
>   ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
> +#else
> +	bl	do_page_fault
> +#endif

Maybe we could always branch to do_page_fault() and get redirected to 
do_hash_fault() from do_page_fault() if BOOK3S64 && !radix_enabled() ?

Another solution is to make it a GAS macro ?

>   	b	interrupt_return_srr
>   
>   1:	bl	do_break
> @@ -1416,6 +1420,7 @@ EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80)
>   EXC_VIRT_END(data_access_slb, 0x4380, 0x80)
>   EXC_COMMON_BEGIN(data_access_slb_common)
>   	GEN_COMMON data_access_slb
> +#ifdef CONFIG_PPC_64S_HASH_MMU
>   BEGIN_MMU_FTR_SECTION
>   	/* HPT case, do SLB fault */
>   	addi	r3,r1,STACK_FRAME_OVERHEAD
> @@ -1428,6 +1433,9 @@ MMU_FTR_SECTION_ELSE
>   	/* Radix case, access is outside page table range */
>   	li	r3,-EFAULT
>   ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
> +#else
> +	li	r3,-EFAULT
> +#endif
>   	std	r3,RESULT(r1)
>   	addi	r3,r1,STACK_FRAME_OVERHEAD
>   	bl	do_bad_segment_interrupt
> @@ -1462,11 +1470,15 @@ EXC_VIRT_END(instruction_access, 0x4400, 0x80)
>   EXC_COMMON_BEGIN(instruction_access_common)
>   	GEN_COMMON instruction_access
>   	addi	r3,r1,STACK_FRAME_OVERHEAD
> +#ifdef CONFIG_PPC_64S_HASH_MMU
>   BEGIN_MMU_FTR_SECTION
>   	bl	do_hash_fault
>   MMU_FTR_SECTION_ELSE
>   	bl	do_page_fault
>   ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
> +#else
> +	bl	do_page_fault
> +#endif

Same as above.

>   	b	interrupt_return_srr
>   
>   

> diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
> index 7d4bcbc3124e..59b1a1833143 100644
> --- a/arch/powerpc/kernel/setup_64.c
> +++ b/arch/powerpc/kernel/setup_64.c
> @@ -887,6 +887,8 @@ void __init setup_per_cpu_areas(void)
>   	} else if (radix_enabled()) {
>   		atom_size = PAGE_SIZE;
>   	} else {
> +#ifdef CONFIG_PPC_64S_HASH_MMU

Use IS_ENABLED()


> +
>   		/*
>   		 * Linear mapping is one of 4K, 1M and 16M.  For 4K, no need
>   		 * to group units.  For larger mappings, use 1M atom which
> @@ -896,6 +898,9 @@ void __init setup_per_cpu_areas(void)
>   			atom_size = PAGE_SIZE;
>   		else
>   			atom_size = 1 << 20;
> +#else
> +		BUILD_BUG(); // radix_enabled() should be constant true
> +#endif
>   	}
>   
>   	if (pcpu_chosen_fc != PCPU_FC_PAGE) {

> diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
> index cd16b407f47e..ab105d33e0b0 100644
> --- a/arch/powerpc/mm/pgtable.c
> +++ b/arch/powerpc/mm/pgtable.c
> @@ -81,9 +81,6 @@ static struct page *maybe_pte_to_page(pte_t pte)
>   
>   static pte_t set_pte_filter_hash(pte_t pte)
>   {
> -	if (radix_enabled())
> -		return pte;
> -
>   	pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
>   	if (pte_looks_normal(pte) && !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
>   				       cpu_has_feature(CPU_FTR_NOEXECUTE))) {
> @@ -112,6 +109,9 @@ static inline pte_t set_pte_filter(pte_t pte)
>   {
>   	struct page *pg;
>   
> +	if (radix_enabled())
> +		return pte;
> +
>   	if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
>   		return set_pte_filter_hash(pte);
>   
> @@ -144,6 +144,10 @@ static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
>   {
>   	struct page *pg;
>   
> +#ifdef CONFIG_PPC_BOOK3S_64
> +	return pte;
> +#endif

Aren't you changing the behaviour here for RADIX ?

Anyway, can use IS_ENABLED()

> +
>   	if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
>   		return pte;
>   
> diff --git a/arch/powerpc/mm/ptdump/Makefile b/arch/powerpc/mm/ptdump/Makefile
> index 4050cbb55acf..b533caaf0910 100644
> --- a/arch/powerpc/mm/ptdump/Makefile
> +++ b/arch/powerpc/mm/ptdump/Makefile
> @@ -10,5 +10,5 @@ obj-$(CONFIG_PPC_BOOK3S_64)	+= book3s64.o
>   
>   ifdef CONFIG_PTDUMP_DEBUGFS
>   obj-$(CONFIG_PPC_BOOK3S_32)	+= bats.o segment_regs.o
> -obj-$(CONFIG_PPC_BOOK3S_64)	+= hashpagetable.o
> +obj-$(CONFIG_PPC_64S_HASH_MMU)	+= hashpagetable.o
>   endif
> diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
> index a208997ade88..01726e7f2c7f 100644
> --- a/arch/powerpc/platforms/Kconfig.cputype
> +++ b/arch/powerpc/platforms/Kconfig.cputype
> @@ -105,6 +105,7 @@ config PPC_BOOK3S_64
>   	select HAVE_MOVE_PMD
>   	select HAVE_MOVE_PUD
>   	select IRQ_WORK
> +	select PPC_64S_HASH_MMU

Not needed

>   	select PPC_MM_SLICES
>   	select PPC_HAVE_KUEP
>   	select PPC_HAVE_KUAP
> @@ -364,6 +365,9 @@ config SPE
>   
>   	  If in doubt, say Y here.
>   
> +config PPC_64S_HASH_MMU
> +	bool

Add
	depends on PPC_BOOK3S_64
	default y

> +
>   config PPC_RADIX_MMU
>   	bool "Radix MMU Support"
>   	depends on PPC_BOOK3S_64

> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index dd8241c009e5..33de8d798c95 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -1160,9 +1160,11 @@ cmds(struct pt_regs *excp)
>   			show_tasks();
>   			break;
>   #ifdef CONFIG_PPC_BOOK3S
> +#ifdef CONFIG_PPC_64S_HASH_MMU

And BOOK3S/32 ???

>   		case 'u':
>   			dump_segments();
>   			break;
> +#endif
>   #elif defined(CONFIG_44x)
>   		case 'u':
>   			dump_tlb_44x();


More information about the Linuxppc-dev mailing list