Skip to content

Commit 014d02c

Browse files
sjitindarsinghmpe
authored andcommitted
powerpc: Update to new option-vector-5 format for CAS
On POWER9 the ibm,client-architecture-support (CAS) negotiation process has been updated to change how the host to guest negotiation is done for the new hash/radix mmu as well as the nest mmu, process tables and guest translation shootdown (GTSE). This is documented in the unreleased PAPR ACR "CAS option vector additions for P9". The host tells the guest which options it supports in ibm,arch-vec-5-platform-support. The guest then chooses a subset of these to request in the CAS call and these are agreed to in the ibm,architecture-vec-5 property of the chosen node. Thus we read ibm,arch-vec-5-platform-support and make our selection before calling CAS. We then parse the ibm,architecture-vec-5 property of the chosen node to check whether we should run as hash or radix. ibm,arch-vec-5-platform-support format: index value pairs: <index, val> ... <index, val> index: Option vector 5 byte number val: Some representation of supported values Signed-off-by: Suraj Jitindar Singh <[email protected]> Acked-by: Paul Mackerras <[email protected]> [mpe: Don't print about unknown options, be consistent with OV5_FEAT] Signed-off-by: Michael Ellerman <[email protected]>
1 parent 12cc9fd commit 014d02c

File tree

3 files changed

+150
-14
lines changed

3 files changed

+150
-14
lines changed

arch/powerpc/include/asm/prom.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,18 @@ struct of_drconf_cell {
160160
#define OV5_PFO_HW_ENCR 0x1120 /* PFO Encryption Accelerator */
161161
#define OV5_SUB_PROCESSORS 0x1501 /* 1,2,or 4 Sub-Processors supported */
162162
#define OV5_XIVE_EXPLOIT 0x1701 /* XIVE exploitation supported */
163-
#define OV5_MMU_RADIX_300 0x1880 /* ISA v3.00 radix MMU supported */
164-
#define OV5_MMU_HASH_300 0x1840 /* ISA v3.00 hash MMU supported */
165-
#define OV5_MMU_SEGM_RADIX 0x1820 /* radix mode (no segmentation) */
166-
#define OV5_MMU_PROC_TBL 0x1810 /* hcall selects SLB or proc table */
167-
#define OV5_MMU_SLB 0x1800 /* always use SLB */
168-
#define OV5_MMU_GTSE 0x1808 /* Guest translation shootdown */
163+
/* MMU Base Architecture */
164+
#define OV5_MMU_SUPPORT 0x18C0 /* MMU Mode Support Mask */
165+
#define OV5_MMU_HASH 0x1800 /* Hash MMU Only */
166+
#define OV5_MMU_RADIX 0x1840 /* Radix MMU Only */
167+
#define OV5_MMU_EITHER 0x1880 /* Hash or Radix Supported */
168+
#define OV5_MMU_DYNAMIC 0x18C0 /* Hash or Radix Can Switch Later */
169+
#define OV5_NMMU 0x1820 /* Nest MMU Available */
170+
/* Hash Table Extensions */
171+
#define OV5_HASH_SEG_TBL 0x1980 /* In Memory Segment Tables Available */
172+
#define OV5_HASH_GTSE 0x1940 /* Guest Translation Shoot Down Avail */
173+
/* Radix Table Extensions */
174+
#define OV5_RADIX_GTSE 0x1A40 /* Guest Translation Shoot Down Avail */
169175

170176
/* Option Vector 6: IBM PAPR hints */
171177
#define OV6_LINUX 0x02 /* Linux is our OS */

arch/powerpc/kernel/prom_init.c

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,14 @@ static unsigned long __initdata prom_tce_alloc_start;
168168
static unsigned long __initdata prom_tce_alloc_end;
169169
#endif
170170

171+
static bool __initdata prom_radix_disable;
172+
173+
struct platform_support {
174+
bool hash_mmu;
175+
bool radix_mmu;
176+
bool radix_gtse;
177+
};
178+
171179
/* Platforms codes are now obsolete in the kernel. Now only used within this
172180
* file and ultimately gone too. Feel free to change them if you need, they
173181
* are not shared with anything outside of this file anymore
@@ -626,6 +634,12 @@ static void __init early_cmdline_parse(void)
626634
prom_memory_limit = ALIGN(prom_memory_limit, 0x1000000);
627635
#endif
628636
}
637+
638+
opt = strstr(prom_cmd_line, "disable_radix");
639+
if (opt) {
640+
prom_debug("Radix disabled from cmdline\n");
641+
prom_radix_disable = true;
642+
}
629643
}
630644

631645
#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
@@ -695,6 +709,8 @@ struct option_vector5 {
695709
u8 byte22;
696710
u8 intarch;
697711
u8 mmu;
712+
u8 hash_ext;
713+
u8 radix_ext;
698714
} __packed;
699715

700716
struct option_vector6 {
@@ -850,8 +866,9 @@ struct ibm_arch_vec __cacheline_aligned ibm_architecture_vec = {
850866
.reserved3 = 0,
851867
.subprocessors = 1,
852868
.intarch = 0,
853-
.mmu = OV5_FEAT(OV5_MMU_RADIX_300) | OV5_FEAT(OV5_MMU_HASH_300) |
854-
OV5_FEAT(OV5_MMU_PROC_TBL) | OV5_FEAT(OV5_MMU_GTSE),
869+
.mmu = 0,
870+
.hash_ext = 0,
871+
.radix_ext = 0,
855872
},
856873

857874
/* option vector 6: IBM PAPR hints */
@@ -990,13 +1007,102 @@ static int __init prom_count_smt_threads(void)
9901007

9911008
}
9921009

1010+
static void __init prom_parse_mmu_model(u8 val,
1011+
struct platform_support *support)
1012+
{
1013+
switch (val) {
1014+
case OV5_FEAT(OV5_MMU_DYNAMIC):
1015+
case OV5_FEAT(OV5_MMU_EITHER): /* Either Available */
1016+
prom_debug("MMU - either supported\n");
1017+
support->radix_mmu = !prom_radix_disable;
1018+
support->hash_mmu = true;
1019+
break;
1020+
case OV5_FEAT(OV5_MMU_RADIX): /* Only Radix */
1021+
prom_debug("MMU - radix only\n");
1022+
if (prom_radix_disable) {
1023+
/*
1024+
* If we __have__ to do radix, we're better off ignoring
1025+
* the command line rather than not booting.
1026+
*/
1027+
prom_printf("WARNING: Ignoring cmdline option disable_radix\n");
1028+
}
1029+
support->radix_mmu = true;
1030+
break;
1031+
case OV5_FEAT(OV5_MMU_HASH):
1032+
prom_debug("MMU - hash only\n");
1033+
support->hash_mmu = true;
1034+
break;
1035+
default:
1036+
prom_debug("Unknown mmu support option: 0x%x\n", val);
1037+
break;
1038+
}
1039+
}
1040+
1041+
static void __init prom_parse_platform_support(u8 index, u8 val,
1042+
struct platform_support *support)
1043+
{
1044+
switch (index) {
1045+
case OV5_INDX(OV5_MMU_SUPPORT): /* MMU Model */
1046+
prom_parse_mmu_model(val & OV5_FEAT(OV5_MMU_SUPPORT), support);
1047+
break;
1048+
case OV5_INDX(OV5_RADIX_GTSE): /* Radix Extensions */
1049+
if (val & OV5_FEAT(OV5_RADIX_GTSE)) {
1050+
prom_debug("Radix - GTSE supported\n");
1051+
support->radix_gtse = true;
1052+
}
1053+
break;
1054+
}
1055+
}
1056+
1057+
static void __init prom_check_platform_support(void)
1058+
{
1059+
struct platform_support supported = {
1060+
.hash_mmu = false,
1061+
.radix_mmu = false,
1062+
.radix_gtse = false
1063+
};
1064+
int prop_len = prom_getproplen(prom.chosen,
1065+
"ibm,arch-vec-5-platform-support");
1066+
if (prop_len > 1) {
1067+
int i;
1068+
u8 vec[prop_len];
1069+
prom_debug("Found ibm,arch-vec-5-platform-support, len: %d\n",
1070+
prop_len);
1071+
prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support",
1072+
&vec, sizeof(vec));
1073+
for (i = 0; i < prop_len; i += 2) {
1074+
prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2
1075+
, vec[i]
1076+
, vec[i + 1]);
1077+
prom_parse_platform_support(vec[i], vec[i + 1],
1078+
&supported);
1079+
}
1080+
}
1081+
1082+
if (supported.radix_mmu && supported.radix_gtse) {
1083+
/* Radix preferred - but we require GTSE for now */
1084+
prom_debug("Asking for radix with GTSE\n");
1085+
ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_RADIX);
1086+
ibm_architecture_vec.vec5.radix_ext = OV5_FEAT(OV5_RADIX_GTSE);
1087+
} else if (supported.hash_mmu) {
1088+
/* Default to hash mmu (if we can) */
1089+
prom_debug("Asking for hash\n");
1090+
ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_HASH);
1091+
} else {
1092+
/* We're probably on a legacy hypervisor */
1093+
prom_debug("Assuming legacy hash support\n");
1094+
}
1095+
}
9931096

9941097
static void __init prom_send_capabilities(void)
9951098
{
9961099
ihandle root;
9971100
prom_arg_t ret;
9981101
u32 cores;
9991102

1103+
/* Check ibm,arch-vec-5-platform-support and fixup vec5 if required */
1104+
prom_check_platform_support();
1105+
10001106
root = call_prom("open", 1, 1, ADDR("/"));
10011107
if (root != 0) {
10021108
/* We need to tell the FW about the number of cores we support.

arch/powerpc/mm/init_64.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -356,18 +356,42 @@ static void early_check_vec5(void)
356356
unsigned long root, chosen;
357357
int size;
358358
const u8 *vec5;
359+
u8 mmu_supported;
359360

360361
root = of_get_flat_dt_root();
361362
chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
362-
if (chosen == -FDT_ERR_NOTFOUND)
363+
if (chosen == -FDT_ERR_NOTFOUND) {
364+
cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
363365
return;
366+
}
364367
vec5 = of_get_flat_dt_prop(chosen, "ibm,architecture-vec-5", &size);
365-
if (!vec5)
368+
if (!vec5) {
369+
cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
366370
return;
367-
if (size <= OV5_INDX(OV5_MMU_RADIX_300) ||
368-
!(vec5[OV5_INDX(OV5_MMU_RADIX_300)] & OV5_FEAT(OV5_MMU_RADIX_300)))
369-
/* Hypervisor doesn't support radix */
371+
}
372+
if (size <= OV5_INDX(OV5_MMU_SUPPORT)) {
370373
cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
374+
return;
375+
}
376+
377+
/* Check for supported configuration */
378+
mmu_supported = vec5[OV5_INDX(OV5_MMU_SUPPORT)] &
379+
OV5_FEAT(OV5_MMU_SUPPORT);
380+
if (mmu_supported == OV5_FEAT(OV5_MMU_RADIX)) {
381+
/* Hypervisor only supports radix - check enabled && GTSE */
382+
if (!early_radix_enabled()) {
383+
pr_warn("WARNING: Ignoring cmdline option disable_radix\n");
384+
}
385+
if (!(vec5[OV5_INDX(OV5_RADIX_GTSE)] &
386+
OV5_FEAT(OV5_RADIX_GTSE))) {
387+
pr_warn("WARNING: Hypervisor doesn't support RADIX with GTSE\n");
388+
}
389+
/* Do radix anyway - the hypervisor said we had to */
390+
cur_cpu_spec->mmu_features |= MMU_FTR_TYPE_RADIX;
391+
} else if (mmu_supported == OV5_FEAT(OV5_MMU_HASH)) {
392+
/* Hypervisor only supports hash - disable radix */
393+
cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
394+
}
371395
}
372396

373397
void __init mmu_early_init_devtree(void)
@@ -383,7 +407,7 @@ void __init mmu_early_init_devtree(void)
383407
* even though the ibm,architecture-vec-5 property created by
384408
* skiboot doesn't have the necessary bits set.
385409
*/
386-
if (early_radix_enabled() && !(mfmsr() & MSR_HV))
410+
if (!(mfmsr() & MSR_HV))
387411
early_check_vec5();
388412

389413
if (early_radix_enabled())

0 commit comments

Comments
 (0)