[Skiboot] [PATCH] cpufeatures: Add tm-suspend-hypervisor-assist and tm-suspend-xer-so-bug node

Stewart Smith stewart at linux.ibm.com
Wed Apr 3 16:48:17 AEDT 2019


tm-suspend-hypervisor-assist for P9 >=DD2.2
And a tm-suspend-xer-so-bug node for P9 DD2.2 only.

I also treat P9P as P9 DD2.3 and add a unit test for the cpufeatures
infrastructure.

Fixes: https://github.com/open-power/skiboot/issues/233
Suggested-by: Paul Mackerras <paulus at ozlabs.org>
Signed-off-by: Stewart Smith <stewart at linux.ibm.com>
---
 core/cpufeatures.c          |  56 ++++++++++++-
 core/test/Makefile.check    |   1 +
 core/test/run-cpufeatures.c | 155 ++++++++++++++++++++++++++++++++++++
 3 files changed, 209 insertions(+), 3 deletions(-)
 create mode 100644 core/test/run-cpufeatures.c

diff --git a/core/cpufeatures.c b/core/cpufeatures.c
index 070419d9cfb7..530dc77f73c4 100644
--- a/core/cpufeatures.c
+++ b/core/cpufeatures.c
@@ -1,4 +1,4 @@
-/* Copyright 2017-2018 IBM Corp.
+/* Copyright 2017-2019 IBM Corp.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -56,8 +56,12 @@
 #define CPU_P8_DD1	(1U << 0)
 #define CPU_P8_DD2	(1U << 1)
 #define CPU_P9_DD1	(1U << 2)
-#define CPU_P9_DD2	(1U << 3)
+#define CPU_P9_DD2_0_1	(1U << 3) // 2.01 or 2.1
 #define CPU_P9P		(1U << 4)
+#define CPU_P9_DD2_2    (1U << 5)
+#define CPU_P9_DD2_3    (1U << 6)
+
+#define CPU_P9_DD2      (CPU_P9_DD2_0_1|CPU_P9_DD2_2|CPU_P9_DD2_3|CPU_P9P)
 
 #define CPU_P8		(CPU_P8_DD1|CPU_P8_DD2)
 #define CPU_P9		(CPU_P9_DD1|CPU_P9_DD2|CPU_P9P)
@@ -721,6 +725,39 @@ static const struct cpu_feature cpu_features_table[] = {
 	HV_NONE, OS_NONE,
 	-1, -1, -1,
 	NULL, },
+
+	/*
+	 * Due to hardware bugs in POWER9, the hypervisor needs to assist
+	 * guests.
+	 *
+	 * Presence of this feature indicates presence of the bug.
+	 *
+	 * See linux kernel commit 4bb3c7a0208f
+	 * and linux Documentation/powerpc/transactional_memory.txt
+	 */
+	{ "tm-suspend-hypervisor-assist",
+	CPU_P9_DD2_2|CPU_P9_DD2_3|CPU_P9P,
+	ISA_V3_0B, USABLE_HV|USABLE_OS,
+	HV_CUSTOM, OS_NONE,
+	-1, -1, -1,
+	NULL, },
+
+	/*
+	 * Due to hardware bugs in POWER9, the hypervisor can hit
+	 * CPU bugs in the operations it needs to do for
+	 * tm-suspend-hypervisor-assist.
+	 *
+	 * Presence of this "feature" means processor is affected by the bug.
+	 *
+	 * See linux kernel commit 4bb3c7a0208f
+	 * and linux Documentation/powerpc/transactional_memory.txt
+	 */
+	{ "tm-suspend-xer-so-bug",
+	CPU_P9_DD2_2,
+	ISA_V3_0B, USABLE_HV,
+	HV_CUSTOM, OS_NONE,
+	-1, -1, -1,
+	NULL, },
 };
 
 static void add_cpu_feature_nodeps(struct dt_node *features,
@@ -905,7 +942,20 @@ void dt_add_cpufeatures(struct dt_node *root)
 		if (is_power9n(version) &&
 			   (PVR_VERS_MAJ(version) == 2)) {
 			/* P9N DD2.x */
-			cpu_feature_cpu = CPU_P9_DD2;
+			switch (PVR_VERS_MIN(version)) {
+			case 0:
+			case 1:
+				cpu_feature_cpu = CPU_P9_DD2_0_1;
+				break;
+			case 2:
+				cpu_feature_cpu = CPU_P9_DD2_2;
+				break;
+			case 3:
+				cpu_feature_cpu = CPU_P9_DD2_3;
+				break;
+			default:
+				assert(0);
+			}
 		} else {
 			assert(0);
 		}
diff --git a/core/test/Makefile.check b/core/test/Makefile.check
index 0fb585e38d2d..8e59ef00e7b6 100644
--- a/core/test/Makefile.check
+++ b/core/test/Makefile.check
@@ -1,6 +1,7 @@
 # -*-Makefile-*-
 CORE_TEST := \
 	core/test/run-bitmap \
+	core/test/run-cpufeatures \
 	core/test/run-device \
 	core/test/run-flash-subpartition \
 	core/test/run-flash-firmware-versions \
diff --git a/core/test/run-cpufeatures.c b/core/test/run-cpufeatures.c
new file mode 100644
index 000000000000..9db21440d6eb
--- /dev/null
+++ b/core/test/run-cpufeatures.c
@@ -0,0 +1,155 @@
+/* Copyright 2019 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <skiboot.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+/* Override this for testing. */
+#define is_rodata(p) fake_is_rodata(p)
+
+char __rodata_start[16];
+#define __rodata_end (__rodata_start + sizeof(__rodata_start))
+
+static inline bool fake_is_rodata(const void *p)
+{
+	return ((char *)p >= __rodata_start && (char *)p < __rodata_end);
+}
+
+#define zalloc(bytes) calloc((bytes), 1)
+
+#include "../device.c"
+#include <assert.h>
+#include "../../test/dt_common.c"
+
+#define __TEST__
+
+static inline unsigned long mfspr(unsigned int spr);
+
+#include <ccan/str/str.c>
+
+#include "../cpufeatures.c"
+
+static unsigned long fake_pvr = PVR_TYPE_P7;
+
+static inline unsigned long mfspr(unsigned int spr)
+{
+	assert(spr == SPR_PVR);
+	return fake_pvr;
+}
+
+int main(void)
+{
+	struct dt_node *dt_root;
+
+	dt_root = dt_new_root("");
+	dt_add_cpufeatures(dt_root);
+	dump_dt(dt_root, 0, true);
+	dt_free(dt_root);
+
+	fake_pvr = (PVR_TYPE_P8E << 16) | 0x100; // P8E DD1.0
+	dt_root = dt_new_root("");
+	dt_add_cpufeatures(dt_root);
+	dump_dt(dt_root, 0, false);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/mmu-radix") == 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-hypervisor-assist") == 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-xer-so-bug") == 0);
+	dt_free(dt_root);
+
+	fake_pvr = (PVR_TYPE_P8E << 16) | 0x200; // P8E DD2.0
+	dt_root = dt_new_root("");
+	dt_add_cpufeatures(dt_root);
+	dump_dt(dt_root, 0, false);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/mmu-radix") == 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-hypervisor-assist") == 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-xer-so-bug") == 0);
+	dt_free(dt_root);
+
+	fake_pvr = (PVR_TYPE_P8 << 16) | 0x100; // P8 DD1.0
+	dt_root = dt_new_root("");
+	dt_add_cpufeatures(dt_root);
+	dump_dt(dt_root, 0, false);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/mmu-radix") == 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-hypervisor-assist") == 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-xer-so-bug") == 0);
+	dt_free(dt_root);
+
+	fake_pvr = (PVR_TYPE_P8 << 16) | 0x200; // P8 DD2.0
+	dt_root = dt_new_root("");
+	dt_add_cpufeatures(dt_root);
+	dump_dt(dt_root, 0, false);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/mmu-radix") == 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-hypervisor-assist") == 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-xer-so-bug") == 0);
+	dt_free(dt_root);
+
+	fake_pvr = (PVR_TYPE_P8NVL << 16) | 0x100; // P8NVL DD1.0
+	dt_root = dt_new_root("");
+	dt_add_cpufeatures(dt_root);
+	dump_dt(dt_root, 0, false);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/mmu-radix") == 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-hypervisor-assist") == 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-xer-so-bug") == 0);
+	dt_free(dt_root);
+
+	fake_pvr = (PVR_TYPE_P9 << 16) | 0x200; // P9 DD2.0
+	dt_root = dt_new_root("");
+	dt_add_cpufeatures(dt_root);
+	dump_dt(dt_root, 0, false);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/mmu-radix"));
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-hypervisor-assist") == 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-xer-so-bug") == 0);
+	dt_free(dt_root);
+
+	fake_pvr = (PVR_TYPE_P9 << 16) | 0x201; // P9 DD2.1
+	dt_root = dt_new_root("");
+	dt_add_cpufeatures(dt_root);
+	dump_dt(dt_root, 0, false);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/mmu-radix"));
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-hypervisor-assist") == 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-xer-so-bug") == 0);
+	dt_free(dt_root);
+
+	fake_pvr = (PVR_TYPE_P9 << 16) | 0x202; // P9 DD2.2
+	dt_root = dt_new_root("");
+	dt_add_cpufeatures(dt_root);
+	dump_dt(dt_root, 0, false);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/mmu-radix"));
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-hypervisor-assist") != 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-xer-so-bug") != 0);
+	dt_free(dt_root);
+
+	fake_pvr = (PVR_TYPE_P9 << 16) | 0x203; // P9 DD2.3
+	dt_root = dt_new_root("");
+	dt_add_cpufeatures(dt_root);
+	dump_dt(dt_root, 0, false);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/mmu-radix"));
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-hypervisor-assist") != 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-xer-so-bug") == 0);
+	dt_free(dt_root);
+
+	fake_pvr = (PVR_TYPE_P9P << 16) | 0x100; // P9P DD1.0
+	dt_root = dt_new_root("");
+	dt_add_cpufeatures(dt_root);
+	dump_dt(dt_root, 0, false);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/mmu-radix"));
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-hypervisor-assist") != 0);
+	assert(dt_find_by_path(dt_root, "cpus/ibm,powerpc-cpu-features/tm-suspend-xer-so-bug") == 0);
+	dt_free(dt_root);
+
+	exit(EXIT_SUCCESS);
+}
-- 
2.20.1



More information about the Skiboot mailing list