Skip to content

Commit 5402e23

Browse files
npigginmpe
authored andcommitted
powerpc/64s: Get LPID bit width from device tree
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 the extra bits yet, this is mainly required to get the PTCR register values correct (so KVM will run but it will not allocate > 4096 LPIDs). OPAL firmware provides this property for POWER10 CPUs since skiboot commit 9b85f7d961f2 ("hdata: add mmu-pid-bits and mmu-lpid-bits for POWER10 CPUs"). Signed-off-by: Nicholas Piggin <[email protected]> Reviewed-by: Fabiano Rosas <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 2c9ac51 commit 5402e23

File tree

4 files changed

+51
-22
lines changed

4 files changed

+51
-22
lines changed

arch/powerpc/include/asm/book3s/64/mmu.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ extern struct patb_entry *partition_tb;
6262
#define PRTS_MASK 0x1f /* process table size field */
6363
#define PRTB_MASK 0x0ffffffffffff000UL
6464

65+
/* Number of supported LPID bits */
66+
extern unsigned int mmu_lpid_bits;
67+
6568
/* Number of supported PID bits */
6669
extern unsigned int mmu_pid_bits;
6770

@@ -76,10 +79,8 @@ extern unsigned long __ro_after_init radix_mem_block_size;
7679
#define PRTB_SIZE_SHIFT (mmu_pid_bits + 4)
7780
#define PRTB_ENTRIES (1ul << mmu_pid_bits)
7881

79-
/*
80-
* Power9 currently only support 64K partition table size.
81-
*/
82-
#define PATB_SIZE_SHIFT 16
82+
#define PATB_SIZE_SHIFT (mmu_lpid_bits + 4)
83+
#define PATB_ENTRIES (1ul << mmu_lpid_bits)
8384

8485
typedef unsigned long mm_context_id_t;
8586
struct spinlock;

arch/powerpc/mm/book3s64/pgtable.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,17 +207,12 @@ void __init mmu_partition_table_init(void)
207207
unsigned long patb_size = 1UL << PATB_SIZE_SHIFT;
208208
unsigned long ptcr;
209209

210-
BUILD_BUG_ON_MSG((PATB_SIZE_SHIFT > 36), "Partition table size too large.");
211210
/* Initialize the Partition Table with no entries */
212211
partition_tb = memblock_alloc(patb_size, patb_size);
213212
if (!partition_tb)
214213
panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
215214
__func__, patb_size, patb_size);
216215

217-
/*
218-
* update partition table control register,
219-
* 64 K size.
220-
*/
221216
ptcr = __pa(partition_tb) | (PATB_SIZE_SHIFT - 12);
222217
set_ptcr_when_no_uv(ptcr);
223218
powernv_set_nmmu_ptcr(ptcr);

arch/powerpc/mm/book3s64/radix_pgtable.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333

3434
#include <trace/events/thp.h>
3535

36-
unsigned int mmu_pid_bits;
3736
unsigned int mmu_base_pid;
3837
unsigned long radix_mem_block_size __ro_after_init;
3938

@@ -357,18 +356,13 @@ static void __init radix_init_pgtable(void)
357356
-1, PAGE_KERNEL));
358357
}
359358

360-
/* Find out how many PID bits are supported */
361359
if (!cpu_has_feature(CPU_FTR_HVMODE) &&
362360
cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
363361
/*
364362
* Older versions of KVM on these machines perfer if the
365363
* guest only uses the low 19 PID bits.
366364
*/
367-
if (!mmu_pid_bits)
368-
mmu_pid_bits = 19;
369-
} else {
370-
if (!mmu_pid_bits)
371-
mmu_pid_bits = 20;
365+
mmu_pid_bits = 19;
372366
}
373367
mmu_base_pid = 1;
374368

@@ -449,11 +443,6 @@ static int __init radix_dt_scan_page_sizes(unsigned long node,
449443
if (type == NULL || strcmp(type, "cpu") != 0)
450444
return 0;
451445

452-
/* Find MMU PID size */
453-
prop = of_get_flat_dt_prop(node, "ibm,mmu-pid-bits", &size);
454-
if (prop && size == 4)
455-
mmu_pid_bits = be32_to_cpup(prop);
456-
457446
/* Grab page size encodings */
458447
prop = of_get_flat_dt_prop(node, "ibm,processor-radix-AP-encodings", &size);
459448
if (!prop)

arch/powerpc/mm/init_64.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,9 @@ void register_page_bootmem_memmap(unsigned long section_nr,
370370
#endif /* CONFIG_SPARSEMEM_VMEMMAP */
371371

372372
#ifdef CONFIG_PPC_BOOK3S_64
373+
unsigned int mmu_lpid_bits;
374+
unsigned int mmu_pid_bits;
375+
373376
static bool disable_radix = !IS_ENABLED(CONFIG_PPC_RADIX_MMU_DEFAULT);
374377

375378
static int __init parse_disable_radix(char *p)
@@ -437,19 +440,60 @@ static void __init early_check_vec5(void)
437440
}
438441
}
439442

443+
static int __init dt_scan_mmu_pid_width(unsigned long node,
444+
const char *uname, int depth,
445+
void *data)
446+
{
447+
int size = 0;
448+
const __be32 *prop;
449+
const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
450+
451+
/* We are scanning "cpu" nodes only */
452+
if (type == NULL || strcmp(type, "cpu") != 0)
453+
return 0;
454+
455+
/* Find MMU LPID, PID register size */
456+
prop = of_get_flat_dt_prop(node, "ibm,mmu-lpid-bits", &size);
457+
if (prop && size == 4)
458+
mmu_lpid_bits = be32_to_cpup(prop);
459+
460+
prop = of_get_flat_dt_prop(node, "ibm,mmu-pid-bits", &size);
461+
if (prop && size == 4)
462+
mmu_pid_bits = be32_to_cpup(prop);
463+
464+
if (!mmu_pid_bits && !mmu_lpid_bits)
465+
return 0;
466+
467+
return 1;
468+
}
469+
440470
void __init mmu_early_init_devtree(void)
441471
{
472+
bool hvmode = !!(mfmsr() & MSR_HV);
473+
442474
/* Disable radix mode based on kernel command line. */
443475
if (disable_radix)
444476
cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
445477

478+
of_scan_flat_dt(dt_scan_mmu_pid_width, NULL);
479+
if (hvmode && !mmu_lpid_bits) {
480+
if (early_cpu_has_feature(CPU_FTR_ARCH_207S))
481+
mmu_lpid_bits = 12; /* POWER8-10 */
482+
else
483+
mmu_lpid_bits = 10; /* POWER7 */
484+
}
485+
if (!mmu_pid_bits) {
486+
if (early_cpu_has_feature(CPU_FTR_ARCH_300))
487+
mmu_pid_bits = 20; /* POWER9-10 */
488+
}
489+
446490
/*
447491
* Check /chosen/ibm,architecture-vec-5 if running as a guest.
448492
* When running bare-metal, we can use radix if we like
449493
* even though the ibm,architecture-vec-5 property created by
450494
* skiboot doesn't have the necessary bits set.
451495
*/
452-
if (!(mfmsr() & MSR_HV))
496+
if (!hvmode)
453497
early_check_vec5();
454498

455499
if (early_radix_enabled()) {

0 commit comments

Comments
 (0)