[CRIU] [PATCH] ppc64: introduce CPU feature checking operations

Laurent Dufour ldufour at linux.vnet.ibm.com
Fri Jan 15 08:39:12 PST 2016


This patch introduces basic CPU feature checking for PowerPC.

Signed-off-by: Laurent Dufour <ldufour at linux.vnet.ibm.com>
---
 arch/ppc64/cpu.c       | 136 +++++++++++++++++++++++++++++++++++++++++++------
 protobuf/cpuinfo.proto |  11 ++++
 2 files changed, 131 insertions(+), 16 deletions(-)

diff --git a/arch/ppc64/cpu.c b/arch/ppc64/cpu.c
index 040fe14fcfb7..d84a782c9047 100644
--- a/arch/ppc64/cpu.c
+++ b/arch/ppc64/cpu.c
@@ -1,45 +1,149 @@
 #undef	LOG_PREFIX
 #define LOG_PREFIX "cpu: "
 
+#include <sys/auxv.h>
 #include <errno.h>
+#include <asm/cputable.h>
+
+#include "asm/types.h"
+#include "asm/cpu.h"
+
+#include "cr_options.h"
+#include "proc_parse.h"
+#include "util.h"
+#include "log.h"
 #include "cpu.h"
 
-bool cpu_has_feature(unsigned int feature)
-{
-	return false;
-}
+#include "protobuf.h"
+#include "protobuf/cpuinfo.pb-c.h"
+
+static uint64_t hwcap[2];
+
+#ifdef __LITTLE_ENDIAN__
+#define CURRENT_ENDIANNESS	CPUINFO_PPC64_ENTRY__ENDIANNESS__LITTLEENDIAN
+#else
+#define CURRENT_ENDIANNESS	CPUINFO_PPC64_ENTRY__ENDIANESS__BIGENDIAN
+#endif
 
 int cpu_init(void)
 {
+	hwcap[0] = getauxval(AT_HWCAP);
+	hwcap[1] = getauxval(AT_HWCAP2);
+
+	if (!hwcap[0] || !hwcap[1]) {
+		pr_err("Can't read the hardware capabilities");
+		return -1;
+	}
 	return 0;
 }
 
 int cpu_dump_cpuinfo(void)
 {
-	return 0;
+	CpuinfoEntry cpu_info = CPUINFO_ENTRY__INIT;
+	CpuinfoPpc64Entry cpu_ppc64_info = CPUINFO_PPC64_ENTRY__INIT;
+	CpuinfoPpc64Entry *cpu_ppc64_info_ptr = &cpu_ppc64_info;
+	struct cr_img *img;
+	int ret = -1;
+
+	img = open_image(CR_FD_CPUINFO, O_DUMP);
+        if (!img)
+                return -1;
+
+	cpu_info.ppc64_entry = &cpu_ppc64_info_ptr;
+	cpu_info.n_ppc64_entry = 1;
+
+	cpu_ppc64_info.endian = CURRENT_ENDIANNESS;
+	cpu_ppc64_info.n_hwcap = 2;
+	cpu_ppc64_info.hwcap = hwcap;
+
+	ret = pb_write_one(img, &cpu_info, PB_CPUINFO);
+
+	close_image(img);
+        return ret;
 }
 
 int cpu_validate_cpuinfo(void)
 {
-	return 0;
-}
+	CpuinfoEntry *cpu_info;
+	CpuinfoPpc64Entry *cpu_ppc64_entry;
+	struct cr_img *img;
+	int ret = -1;
+        img = open_image(CR_FD_CPUINFO, O_RSTR);
+        if (!img)
+                return -1;
 
-int cpu_dump_cpuinfo_single(void)
-{
-	return -ENOTSUP;
-}
+        if (pb_read_one(img, &cpu_info, PB_CPUINFO) < 0)
+                goto error;
 
-int cpu_validate_image_cpuinfo_single(void)
-{
-	return -ENOTSUP;
+	if (cpu_info->n_ppc64_entry != 1) {
+		pr_err("No PPC64 related entry in image");
+		goto error;
+	}
+	cpu_ppc64_entry = cpu_info->ppc64_entry[0];
+
+	if (cpu_ppc64_entry->endian != CURRENT_ENDIANNESS) {
+		pr_err("Bad endianness");
+		goto error;
+	}
+
+	if (cpu_ppc64_entry->n_hwcap != 2) {
+		pr_err("Hardware capabilities information missing\n");
+		goto error;
+	}
+
+#define CHECK_FEATURE(s,f) do {						\
+		if ((cpu_ppc64_entry->hwcap[s] & f) && !(hwcap[s] & f)) { \
+			pr_err("CPU Feature %s required by image "	\
+			       "is not supported on host.\n", #f);	\
+			goto error;					\
+		}							\
+	} while(0)
+
+#define REQUIRE_FEATURE(s,f) do {					\
+		if (!(cpu_ppc64_entry->hwcap[s] & f)) {			\
+			pr_err("CPU Feature %s missing in image.\n", #f); \
+			goto error;					\
+		}							\
+	} while(0)
+
+	REQUIRE_FEATURE(0, PPC_FEATURE_64);
+	REQUIRE_FEATURE(0, PPC_FEATURE_HAS_FPU);
+	REQUIRE_FEATURE(0, PPC_FEATURE_HAS_MMU);
+	REQUIRE_FEATURE(0, PPC_FEATURE_HAS_VSX);
+	REQUIRE_FEATURE(1, PPC_FEATURE2_ARCH_2_07);
+
+	CHECK_FEATURE(0, PPC_FEATURE_TRUE_LE);
+	CHECK_FEATURE(1, PPC_FEATURE2_HTM);
+	CHECK_FEATURE(1, PPC_FEATURE2_DSCR);
+	CHECK_FEATURE(1, PPC_FEATURE2_EBB);
+	CHECK_FEATURE(1, PPC_FEATURE2_ISEL);
+	CHECK_FEATURE(1, PPC_FEATURE2_TAR);
+	CHECK_FEATURE(1, PPC_FEATURE2_VEC_CRYPTO);
+
+	ret = 0;
+error:
+	close_image(img);
+	return ret;
 }
 
 int cpuinfo_dump(void)
 {
-	return -ENOTSUP;
+        if (cpu_init())
+                return -1;
+
+        if (cpu_dump_cpuinfo())
+                return -1;
+
+        return 0;
 }
 
 int cpuinfo_check(void)
 {
-	return -ENOTSUP;
+        if (cpu_init())
+                return -1;
+
+        if (cpu_validate_cpuinfo())
+                return 1;
+
+	return 0;
 }
diff --git a/protobuf/cpuinfo.proto b/protobuf/cpuinfo.proto
index a62ff19b5c83..f5de73aa20e9 100644
--- a/protobuf/cpuinfo.proto
+++ b/protobuf/cpuinfo.proto
@@ -15,6 +15,16 @@ message cpuinfo_x86_entry {
 	optional string			model_id	= 7;
 }
 
+message cpuinfo_ppc64_entry {
+	enum endianness {
+		BIGENDIAN	= 0;
+		LITTLEENDIAN	= 1;
+	}
+
+	required endianness	endian		= 1;
+	repeated uint64		hwcap		= 2;
+}
+
 message cpuinfo_entry {
 	/*
 	 * Usually on SMP system there should be same CPUs
@@ -22,4 +32,5 @@ message cpuinfo_entry {
 	 * various CPUs so @repeated used.
 	 */
 	repeated cpuinfo_x86_entry	x86_entry	= 1;
+	repeated cpuinfo_ppc64_entry	ppc64_entry	= 2;
 }
-- 
1.9.1



More information about the CRIU mailing list