[RFC NO-MERGE 2/2] arch/powerpc/CAS: Update to new option-vector-5 format for CAS

Suraj Jitindar Singh sjitindarsingh at gmail.com
Tue Feb 21 17:06:11 AEDT 2017


The CAS 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).

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.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh at gmail.com>
---
 arch/powerpc/include/asm/prom.h | 16 ++++---
 arch/powerpc/kernel/prom_init.c | 99 +++++++++++++++++++++++++++++++++++++++--
 arch/powerpc/mm/init_64.c       | 31 ++++++++++---
 3 files changed, 130 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 8af2546..19d2e84 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -158,12 +158,16 @@ struct of_drconf_cell {
 #define OV5_PFO_HW_ENCR		0x1120	/* PFO Encryption Accelerator */
 #define OV5_SUB_PROCESSORS	0x1501	/* 1,2,or 4 Sub-Processors supported */
 #define OV5_XIVE_EXPLOIT	0x1701	/* XIVE exploitation supported */
-#define OV5_MMU_RADIX_300	0x1880	/* ISA v3.00 radix MMU supported */
-#define OV5_MMU_HASH_300	0x1840	/* ISA v3.00 hash MMU supported */
-#define OV5_MMU_SEGM_RADIX	0x1820	/* radix mode (no segmentation) */
-#define OV5_MMU_PROC_TBL	0x1810	/* hcall selects SLB or proc table */
-#define OV5_MMU_SLB		0x1800	/* always use SLB */
-#define OV5_MMU_GTSE		0x1808	/* Guest translation shootdown */
+/* MMU Base Architecture */
+#define OV5_MMU_HASH_300	0x1800	/* ISA v3.00 Hash MMU Only */
+#define OV5_MMU_RADIX_300	0x1840	/* ISA v3.00 Radix MMU Only */
+#define OV5_MMU_EITHER_300	0x1880	/* ISA v3.00 Hash or Radix Supported */
+#define OV5_NMMU		0x1820	/* Nest MMU Available */
+/* Hash Table Extensions */
+#define OV5_HASH_SEG_TBL	0x1980	/* In Memory Segment Tables Available */
+#define OV5_HASH_GTSE		0x1940	/* Guest Translation Shoot Down Avail */
+/* Radix Table Extensions */
+#define OV5_RADIX_GTSE		0x1A40	/* Guest Translation Shoot Down Avail */
 
 /* Option Vector 6: IBM PAPR hints */
 #define OV6_LINUX		0x02	/* Linux is our OS */
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 37b5a29..8272104 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -168,6 +168,8 @@ static unsigned long __initdata prom_tce_alloc_start;
 static unsigned long __initdata prom_tce_alloc_end;
 #endif
 
+static bool __initdata prom_radix_disable;
+
 /* Platforms codes are now obsolete in the kernel. Now only used within this
  * file and ultimately gone too. Feel free to change them if you need, they
  * are not shared with anything outside of this file anymore
@@ -626,6 +628,12 @@ static void __init early_cmdline_parse(void)
 		prom_memory_limit = ALIGN(prom_memory_limit, 0x1000000);
 #endif
 	}
+
+	opt = strstr(prom_cmd_line, "disable_radix");
+	if (opt) {
+		prom_debug("Radix disabled from cmdline\n");
+		prom_radix_disable = true;
+	}
 }
 
 #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
@@ -693,8 +701,10 @@ struct option_vector5 {
 	__be16 reserved3;
 	u8 subprocessors;
 	u8 byte22;
-	u8 intarch;
+	u8 xive;
 	u8 mmu;
+	u8 hash_ext;
+	u8 radix_ext;
 } __packed;
 
 struct option_vector6 {
@@ -849,9 +859,10 @@ struct ibm_arch_vec __cacheline_aligned ibm_architecture_vec = {
 		.reserved2 = 0,
 		.reserved3 = 0,
 		.subprocessors = 1,
-		.intarch = 0,
-		.mmu = OV5_FEAT(OV5_MMU_RADIX_300) | OV5_FEAT(OV5_MMU_HASH_300) |
-			OV5_FEAT(OV5_MMU_PROC_TBL) | OV5_FEAT(OV5_MMU_GTSE),
+		.xive = 0,
+		.mmu = 0,
+		.hash_ext = 0,
+		.radix_ext = 0,
 	},
 
 	/* option vector 6: IBM PAPR hints */
@@ -990,6 +1001,83 @@ static int __init prom_count_smt_threads(void)
 
 }
 
+static void __init prom_check_platform_support(void)
+{
+	int prop_len, i;
+	bool radix_gtse = false, radix_mmu = false, hash_mmu = false;
+
+	prop_len = prom_getproplen(prom.chosen,
+				   "ibm,arch-vec-5-platform-support");
+	if (prop_len > 1) {
+		u8 val[prop_len];
+		prom_debug("Found ibm,arch-vec-5-platform-support, len: %d\n",
+			   prop_len);
+		prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support",
+			     &val, sizeof(val));
+		for (i = 0; i < prop_len; i += 2) {
+			u8 b1 = val[i], b2 = val[i+1];
+			prom_debug("%d: nbyte = %x, val = %x\n", i/2, b1, b2);
+			switch (b1) {
+			case OV5_INDX(OV5_XIVE_EXPLOIT):
+				/* Unimplemented - Ignore */
+				break;
+			case OV5_INDX(OV5_MMU_EITHER_300):
+				if (b2 == OV5_FEAT(OV5_MMU_EITHER_300)) {
+					/* Either Available */
+					prom_debug("MMU - either supported\n");
+					radix_mmu = !prom_radix_disable;
+					hash_mmu = true;
+				} else if (b2 == OV5_FEAT(OV5_MMU_RADIX_300)) {
+					/* Radix Only */
+					prom_debug("MMU - radix only\n");
+					if (prom_radix_disable) {
+						prom_printf("WARNING: Ignoring "
+							    "cmdline option \""
+							    "disable_radix\"\n"
+							    );
+					}
+					radix_mmu = true;
+				} else if (b2 == OV5_FEAT(OV5_MMU_HASH_300)) {
+					/* Hash Only */
+					prom_debug("MMU - hash only\n");
+					hash_mmu = true;
+				}
+				break;
+			case OV5_INDX(OV5_HASH_SEG_TBL):
+				/* Unimplemented - Ignore */
+				break;
+			case OV5_INDX(OV5_RADIX_GTSE):
+				if (val[i+1] & OV5_FEAT(OV5_RADIX_GTSE)) {
+					prom_debug("GTSE supported\n");
+					radix_gtse = true;
+				}
+				break;
+			default:
+				prom_printf("WARNING: Invalid byte index <%d>"
+					    " in ibm,arch-vec-5-platform-"
+					    "support\n", val[i]);
+				break;
+			}
+		}
+	} else {
+		prom_printf("WARNING: Invalid len <%d> of ibm,arch-vec-5"
+			    "-platform-support\n", prop_len);
+	}
+
+	if (radix_mmu && radix_gtse) {
+		/* Radix preferred - but we require GTSE for now */
+		prom_debug("Asking for radix with GTSE\n");
+		ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_RADIX_300);
+		ibm_architecture_vec.vec5.radix_ext = OV5_FEAT(OV5_RADIX_GTSE);
+	} else if (hash_mmu) {
+		/* Default to hash mmu (if we can) */
+		prom_debug("Asking for hash\n");
+		ibm_architecture_vec.vec5.mmu = OV5_FEAT(OV5_MMU_HASH_300);
+	} else {
+		/* Unsupported Configuration */
+		prom_printf("WARNING: unsupported host platform MMU config\n");
+	}
+}
 
 static void __init prom_send_capabilities(void)
 {
@@ -997,6 +1085,9 @@ static void __init prom_send_capabilities(void)
 	prom_arg_t ret;
 	u32 cores;
 
+	/* Check ibm,arch-vec-5-platform-support and fixup vec5 if required */
+	prom_check_platform_support();
+
 	root = call_prom("open", 1, 1, ADDR("/"));
 	if (root != 0) {
 		/* We need to tell the FW about the number of cores we support.
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 6aa3b76..17262da 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -359,15 +359,34 @@ static void early_check_vec5(void)
 
 	root = of_get_flat_dt_root();
 	chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
-	if (chosen == -FDT_ERR_NOTFOUND)
+	if (chosen == -FDT_ERR_NOTFOUND) {
+		cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
 		return;
+	}
 	vec5 = of_get_flat_dt_prop(chosen, "ibm,architecture-vec-5", &size);
-	if (!vec5)
+	if (!vec5) {
+		cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
 		return;
-	if (size <= OV5_INDX(OV5_MMU_RADIX_300) ||
-	    !(vec5[OV5_INDX(OV5_MMU_RADIX_300)] & OV5_FEAT(OV5_MMU_RADIX_300)))
-		/* Hypervisor doesn't support radix */
+	}
+	if (size <= OV5_INDX(OV5_MMU_RADIX_300)) {
 		cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
+		return;
+	}
+
+	/* Check for supported configuration */
+	if (vec5[OV5_INDX(OV5_MMU_EITHER_300)] == OV5_FEAT(OV5_MMU_RADIX_300)) {
+		/* Hypervisor only supports radix - check enabled && GTSE */
+		WARN(!early_radix_enabled() ||
+		     !(vec5[OV5_INDX(OV5_RADIX_GTSE)] &
+		       OV5_FEAT(OV5_RADIX_GTSE)),
+		     "WARNING: Unsupported MMU configuration in vec5\n");
+		/* Do radix anyway - the hypervisor said we had to */
+		cur_cpu_spec->mmu_features |= MMU_FTR_TYPE_RADIX;
+	} else if (vec5[OV5_INDX(OV5_MMU_EITHER_300)] ==
+		   OV5_FEAT(OV5_MMU_HASH_300)) {
+		/* Hypervisor only supports hash - disable radix */
+		cur_cpu_spec->mmu_features &= ~MMU_FTR_TYPE_RADIX;
+	}
 }
 
 void __init mmu_early_init_devtree(void)
@@ -383,7 +402,7 @@ void __init mmu_early_init_devtree(void)
 	 * even though the ibm,architecture-vec-5 property created by
 	 * skiboot doesn't have the necessary bits set.
 	 */
-	if (early_radix_enabled() && !(mfmsr() & MSR_HV))
+	if (!(mfmsr() & MSR_HV))
 		early_check_vec5();
 
 	if (early_radix_enabled())
-- 
2.5.5



More information about the Linuxppc-dev mailing list