[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