[PATCH v2] powerpc/64s: Get LPID bit width from device tree

Fabiano Rosas farosas at linux.ibm.com
Wed Nov 10 22:02:45 AEDT 2021


Nicholas Piggin <npiggin at gmail.com> writes:

> Allow the LPID bit width and partition table size to be set at runtime
> from the device tree.
>
> Move the PID bit width detection into the same place.
>
> KVM does not support using different sizes yet, this is mainly required
> to get the PTCR register values correct.
>
> Signed-off-by: Nicholas Piggin <npiggin at gmail.com>

Reviewed-by: Fabiano Rosas <farosas at linux.ibm.com>

> ---
>  arch/powerpc/include/asm/book3s/64/mmu.h |  9 +++--
>  arch/powerpc/mm/book3s64/pgtable.c       |  5 ---
>  arch/powerpc/mm/book3s64/radix_pgtable.c | 13 +------
>  arch/powerpc/mm/init_64.c                | 47 +++++++++++++++++++++++-
>  4 files changed, 52 insertions(+), 22 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h
> index c02f42d1031e..8c500dd6fee4 100644
> --- a/arch/powerpc/include/asm/book3s/64/mmu.h
> +++ b/arch/powerpc/include/asm/book3s/64/mmu.h
> @@ -62,6 +62,9 @@ extern struct patb_entry *partition_tb;
>  #define PRTS_MASK	0x1f		/* process table size field */
>  #define PRTB_MASK	0x0ffffffffffff000UL
>  
> +/* Number of supported LPID bits */
> +extern unsigned int mmu_lpid_bits;
> +
>  /* Number of supported PID bits */
>  extern unsigned int mmu_pid_bits;
>  
> @@ -76,10 +79,8 @@ extern unsigned long __ro_after_init radix_mem_block_size;
>  #define PRTB_SIZE_SHIFT	(mmu_pid_bits + 4)
>  #define PRTB_ENTRIES	(1ul << mmu_pid_bits)
>  
> -/*
> - * Power9 currently only support 64K partition table size.
> - */
> -#define PATB_SIZE_SHIFT	16
> +#define PATB_SIZE_SHIFT	(mmu_lpid_bits + 4)
> +#define PATB_ENTRIES	(1ul << mmu_lpid_bits)
>  
>  typedef unsigned long mm_context_id_t;
>  struct spinlock;
> diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c
> index 9e16c7b1a6c5..13d1fbddecb9 100644
> --- a/arch/powerpc/mm/book3s64/pgtable.c
> +++ b/arch/powerpc/mm/book3s64/pgtable.c
> @@ -207,17 +207,12 @@ void __init mmu_partition_table_init(void)
>  	unsigned long patb_size = 1UL << PATB_SIZE_SHIFT;
>  	unsigned long ptcr;
>  
> -	BUILD_BUG_ON_MSG((PATB_SIZE_SHIFT > 36), "Partition table size too large.");
>  	/* Initialize the Partition Table with no entries */
>  	partition_tb = memblock_alloc(patb_size, patb_size);
>  	if (!partition_tb)
>  		panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
>  		      __func__, patb_size, patb_size);
>  
> -	/*
> -	 * update partition table control register,
> -	 * 64 K size.
> -	 */
>  	ptcr = __pa(partition_tb) | (PATB_SIZE_SHIFT - 12);
>  	set_ptcr_when_no_uv(ptcr);
>  	powernv_set_nmmu_ptcr(ptcr);
> diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
> index ae20add7954a..1c855434f8dc 100644
> --- a/arch/powerpc/mm/book3s64/radix_pgtable.c
> +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
> @@ -33,7 +33,6 @@
>  
>  #include <trace/events/thp.h>
>  
> -unsigned int mmu_pid_bits;
>  unsigned int mmu_base_pid;
>  unsigned long radix_mem_block_size __ro_after_init;
>  
> @@ -357,18 +356,13 @@ static void __init radix_init_pgtable(void)
>  						-1, PAGE_KERNEL));
>  	}
>  
> -	/* Find out how many PID bits are supported */
>  	if (!cpu_has_feature(CPU_FTR_HVMODE) &&
>  			cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
>  		/*
>  		 * Older versions of KVM on these machines perfer if the
>  		 * guest only uses the low 19 PID bits.
>  		 */
> -		if (!mmu_pid_bits)
> -			mmu_pid_bits = 19;
> -	} else {
> -		if (!mmu_pid_bits)
> -			mmu_pid_bits = 20;
> +		mmu_pid_bits = 19;
>  	}
>  	mmu_base_pid = 1;
>  
> @@ -449,11 +443,6 @@ static int __init radix_dt_scan_page_sizes(unsigned long node,
>  	if (type == NULL || strcmp(type, "cpu") != 0)
>  		return 0;
>  
> -	/* Find MMU PID size */
> -	prop = of_get_flat_dt_prop(node, "ibm,mmu-pid-bits", &size);
> -	if (prop && size == 4)
> -		mmu_pid_bits = be32_to_cpup(prop);
> -
>  	/* Grab page size encodings */
>  	prop = of_get_flat_dt_prop(node, "ibm,processor-radix-AP-encodings", &size);
>  	if (!prop)
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index 386be136026e..04f45fcb1222 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -370,6 +370,9 @@ void register_page_bootmem_memmap(unsigned long section_nr,
>  #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>  
>  #ifdef CONFIG_PPC_BOOK3S_64
> +unsigned int mmu_lpid_bits;
> +unsigned int mmu_pid_bits;
> +
>  static bool disable_radix = !IS_ENABLED(CONFIG_PPC_RADIX_MMU_DEFAULT);
>  
>  static int __init parse_disable_radix(char *p)
> @@ -437,19 +440,61 @@ static void __init early_check_vec5(void)
>  	}
>  }
>  
> +static int __init dt_scan_mmu_pid_width(unsigned long node,
> +					   const char *uname, int depth,
> +					   void *data)
> +{
> +	int size = 0;
> +	const __be32 *prop;
> +	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
> +
> +	/* We are scanning "cpu" nodes only */
> +	if (type == NULL || strcmp(type, "cpu") != 0)
> +		return 0;
> +
> +	/* Find MMU LPID, PID register size */
> +	prop = of_get_flat_dt_prop(node, "ibm,mmu-lpid-bits", &size);
> +	if (prop && size == 4)
> +		mmu_lpid_bits = be32_to_cpup(prop);
> +
> +	prop = of_get_flat_dt_prop(node, "ibm,mmu-pid-bits", &size);
> +	if (prop && size == 4)
> +		mmu_pid_bits = be32_to_cpup(prop);
> +
> +	if (!mmu_pid_bits && !mmu_lpid_bits)
> +		return 0;
> +
> +	return 1;
> +}
> +
>  void __init mmu_early_init_devtree(void)
>  {
> +	int rc;
> +	bool hvmode = !!(mfmsr() & MSR_HV);
> +
>  	/* Disable radix mode based on kernel command line. */
>  	if (disable_radix)
>  		cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
>  
> +	rc = of_scan_flat_dt(dt_scan_mmu_pid_width, NULL);
> +	if (hvmode && !mmu_lpid_bits) {
> +		if (early_cpu_has_feature(CPU_FTR_ARCH_207S))
> +			mmu_lpid_bits = 12; /* POWER8-10 */
> +		else
> +			mmu_lpid_bits = 10; /* POWER7 */
> +	}
> +	if (!mmu_pid_bits) {
> +		if (early_cpu_has_feature(CPU_FTR_ARCH_300))
> +			mmu_pid_bits = 20; /* POWER9-10 */
> +	}
> +
>  	/*
>  	 * Check /chosen/ibm,architecture-vec-5 if running as a guest.
>  	 * When running bare-metal, we can use radix if we like
>  	 * even though the ibm,architecture-vec-5 property created by
>  	 * skiboot doesn't have the necessary bits set.
>  	 */
> -	if (!(mfmsr() & MSR_HV))
> +	if (!hvmode)
>  		early_check_vec5();
>  
>  	if (early_radix_enabled()) {


More information about the Linuxppc-dev mailing list