[CRIU] [PATCH 14/15] cpuinfo: Add "cpuinfo (dump|check)" commands

Cyrill Gorcunov gorcunov at openvz.org
Fri Sep 19 07:03:16 PDT 2014


This commands are needed to write and test cpuinfo solely
mostly to be able to detect if the node we're about to migrate
will be able to run code we're dumped.

"cpuinfo dump" writes runtime cpu features and additional info
into "cpuinfo.img" file while "cpuinfo check" does the reverse:
reads cpu features from image and test if runtime cpu is matching it.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 Documentation/criu.txt |  7 +++++++
 arch/aarch64/cpu.c     | 11 +++++++++++
 arch/arm/cpu.c         | 11 +++++++++++
 arch/x86/cpu.c         | 52 +++++++++++++++++++++++++++++++++++++++++++++++---
 crtools.c              | 12 ++++++++++++
 include/cpu.h          |  2 ++
 6 files changed, 92 insertions(+), 3 deletions(-)

diff --git a/Documentation/criu.txt b/Documentation/criu.txt
index c10093e133c4..6464984ded18 100644
--- a/Documentation/criu.txt
+++ b/Documentation/criu.txt
@@ -50,6 +50,13 @@ Starts pagemap data deduplication procedure, where *criu* scans over all
 pagemap files and tries to minimalize the number of pagemap entries by
 obtaining the references from a parent pagemap image.
 
+*cpuinfo* *dump*::
+Writes information about currently running CPU and its features into an image.
+
+*cpuinfo* *check*::
+Reads information about CPU from an image file and checks if it is compatible
+with currently running CPU.
+
 OPTIONS
 -------
 *-c*::
diff --git a/arch/aarch64/cpu.c b/arch/aarch64/cpu.c
index f13d635c2c5a..2ab78b179fbf 100644
--- a/arch/aarch64/cpu.c
+++ b/arch/aarch64/cpu.c
@@ -1,6 +1,7 @@
 #undef	LOG_PREFIX
 #define LOG_PREFIX "cpu: "
 
+#include <errno.h>
 #include "cpu.h"
 
 void cpu_set_feature(unsigned int feature)
@@ -22,7 +23,17 @@ int cpu_dump_cpuinfo(void)
 	return 0;
 }
 
+int cpu_dump_cpuinfo_single(void)
+{
+	return -ENOTSUP;
+}
+
 int cpu_validate_image_cpuinfo(void)
 {
 	return 0;
 }
+
+int cpu_validate_image_cpuinfo_single(void)
+{
+	return -ENOTSUP;
+}
diff --git a/arch/arm/cpu.c b/arch/arm/cpu.c
index f13d635c2c5a..2ab78b179fbf 100644
--- a/arch/arm/cpu.c
+++ b/arch/arm/cpu.c
@@ -1,6 +1,7 @@
 #undef	LOG_PREFIX
 #define LOG_PREFIX "cpu: "
 
+#include <errno.h>
 #include "cpu.h"
 
 void cpu_set_feature(unsigned int feature)
@@ -22,7 +23,17 @@ int cpu_dump_cpuinfo(void)
 	return 0;
 }
 
+int cpu_dump_cpuinfo_single(void)
+{
+	return -ENOTSUP;
+}
+
 int cpu_validate_image_cpuinfo(void)
 {
 	return 0;
 }
+
+int cpu_validate_image_cpuinfo_single(void)
+{
+	return -ENOTSUP;
+}
diff --git a/arch/x86/cpu.c b/arch/x86/cpu.c
index d43fdbbeac04..2a8dab0d96a4 100644
--- a/arch/x86/cpu.c
+++ b/arch/x86/cpu.c
@@ -354,6 +354,21 @@ int cpu_dump_cpuinfo(void)
 	return 0;
 }
 
+int cpu_dump_cpuinfo_single(void)
+{
+	int ret;
+
+	ret = cpu_init();
+	if (ret)
+		goto err;
+
+	ret = cpu_dump_cpuinfo();
+	if (ret)
+		goto err;
+err:
+	return ret;
+}
+
 int cpu_validate_features(CpuinfoX86Entry *img_x86_entry)
 {
 	size_t size;
@@ -378,7 +393,13 @@ int cpu_validate_features(CpuinfoX86Entry *img_x86_entry)
 		return -1;
 	}
 
-	if (opts.cpu_cap & CPU_CAP_FPU) {
+	/*
+	 * FPU testing must be specfied explicitly as a sole option.
+	 * This is the case when user dumped programs on different
+	 * cpu but knows that no special instructions is used except
+	 * FPU ones.
+	 */
+	if ((opts.cpu_cap & ~CPU_CAP_FPU) == 0) {
 		/*
 		 * Check if runtime CPU has all FPU related
 		 * bits non less capable.
@@ -404,8 +425,12 @@ int cpu_validate_features(CpuinfoX86Entry *img_x86_entry)
 #undef __mismatch_fpu_bit
 	}
 
-	return memcmp(img_x86_entry->features, cpu_features,
-		      min(size, sizeof(cpu_features)));
+	size = min(size, sizeof(cpu_features));
+	if (memcmp(img_x86_entry->features, cpu_features, size)) {
+		pr_err("Mismatch in CPU features detected\n");
+		return -1;
+	}
+	return 0;
 }
 
 int cpu_validate_image_cpuinfo(void)
@@ -450,3 +475,24 @@ err:
 	close(fd);
 	return ret;
 }
+
+int cpu_validate_image_cpuinfo_single(void)
+{
+	int ret;
+
+	ret = cpu_init();
+	if (ret)
+		goto err;
+
+	/*
+	 * Force to check all caps because its been
+	 * called as a special command from options.
+	 */
+	opts.cpu_cap = CPU_CAP_ALL;
+
+	ret = cpu_validate_image_cpuinfo();
+	if (ret)
+		goto err;
+err:
+	return ret;
+}
diff --git a/crtools.c b/crtools.c
index 65c09332144b..67b06c545df0 100644
--- a/crtools.c
+++ b/crtools.c
@@ -28,6 +28,7 @@
 #include "files.h"
 #include "sk-inet.h"
 #include "net.h"
+#include "cpu.h"
 #include "version.h"
 #include "page-xfer.h"
 #include "tty.h"
@@ -522,6 +523,15 @@ int main(int argc, char *argv[], char *envp[])
 	if (!strcmp(argv[optind], "dedup"))
 		return cr_dedup() != 0;
 
+	if (!strcmp(argv[optind], "cpuinfo")) {
+		if (!argv[optind + 1])
+			goto usage;
+		if (!strcmp(argv[optind + 1], "dump"))
+		    return cpu_dump_cpuinfo_single();
+		else if (!strcmp(argv[optind + 1], "check"))
+			return cpu_validate_image_cpuinfo_single();
+	}
+
 	pr_msg("Error: unknown command: %s\n", argv[optind]);
 usage:
 	pr_msg("\n"
@@ -545,6 +555,8 @@ usage:
 "  page-server    launch page server\n"
 "  service        launch service\n"
 "  dedup          remove duplicates in memory dump\n"
+"  cpuinfo dump   writes cpu information into image file\n"
+"  cpuinfo check  validates cpu information from image file\n"
 	);
 
 	if (usage_error) {
diff --git a/include/cpu.h b/include/cpu.h
index c3e3cc6edc2e..cbb1399d0ff7 100644
--- a/include/cpu.h
+++ b/include/cpu.h
@@ -7,6 +7,8 @@ extern void cpu_set_feature(unsigned int feature);
 extern bool cpu_has_feature(unsigned int feature);
 extern int cpu_init(void);
 extern int cpu_dump_cpuinfo(void);
+extern int cpu_dump_cpuinfo_single(void);
 extern int cpu_validate_image_cpuinfo(void);
+extern int cpu_validate_image_cpuinfo_single(void);
 
 #endif /* __CR_CPU_H__ */
-- 
1.9.3



More information about the CRIU mailing list