[CRIU] [PATCH 57/78] compel: Move cpu interface to compel
Cyrill Gorcunov
gorcunov at openvz.org
Mon Nov 7 08:36:42 PST 2016
We will need it when parasite engine will be creating signal frames.
Export appropriate headers and use it in CRIU by linking with libcompel.a.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
Makefile | 4 +-
Makefile.compel | 1 +
compel/Makefile | 2 +
compel/arch/aarch64/src/lib/cpu.c | 28 +++
compel/arch/aarch64/src/lib/include/uapi/asm/cpu.h | 6 +
.../src/lib/include/uapi/asm/processor-flags.h | 4 +
compel/arch/arm/src/lib/cpu.c | 28 +++
compel/arch/arm/src/lib/include/uapi/asm/cpu.h | 6 +
.../lib/include/{ => uapi/asm}/processor-flags.h | 0
compel/arch/ppc64/src/lib/cpu.c | 42 +++++
compel/arch/ppc64/src/lib/include/uapi/asm/cpu.h | 10 ++
.../src/lib/include/uapi/asm/processor-flags.h | 4 +
.../ppc64/src/lib/include/uapi/asm/processor.h | 4 +
compel/arch/x86/src/lib/cpu.c | 189 +++++++++++++++++++++
.../arch/x86/src/lib/include/uapi}/asm/cpu.h | 25 +--
.../lib/include/{ => uapi/asm}/processor-flags.h | 0
compel/include/uapi/cpu.h | 14 ++
criu/Makefile | 1 +
criu/arch/aarch64/cpu.c | 5 -
criu/arch/aarch64/crtools.c | 2 +
criu/arch/aarch64/include/asm/cpu.h | 1 -
criu/arch/arm/cpu.c | 5 -
criu/arch/arm/crtools.c | 2 +
criu/arch/arm/include/asm/cpu.h | 1 -
criu/arch/ppc64/cpu.c | 17 +-
criu/arch/ppc64/include/asm/cpu.h | 1 -
criu/arch/x86/cpu.c | 175 +------------------
criu/arch/x86/infect.c | 3 +-
criu/include/cpu.h | 3 +-
29 files changed, 365 insertions(+), 218 deletions(-)
create mode 100644 compel/arch/aarch64/src/lib/cpu.c
create mode 100644 compel/arch/aarch64/src/lib/include/uapi/asm/cpu.h
create mode 100644 compel/arch/aarch64/src/lib/include/uapi/asm/processor-flags.h
create mode 100644 compel/arch/arm/src/lib/cpu.c
create mode 100644 compel/arch/arm/src/lib/include/uapi/asm/cpu.h
rename compel/arch/arm/src/lib/include/{ => uapi/asm}/processor-flags.h (100%)
create mode 100644 compel/arch/ppc64/src/lib/cpu.c
create mode 100644 compel/arch/ppc64/src/lib/include/uapi/asm/cpu.h
create mode 100644 compel/arch/ppc64/src/lib/include/uapi/asm/processor-flags.h
create mode 100644 compel/arch/ppc64/src/lib/include/uapi/asm/processor.h
create mode 100644 compel/arch/x86/src/lib/cpu.c
rename {criu/arch/x86/include => compel/arch/x86/src/lib/include/uapi}/asm/cpu.h (95%)
rename compel/arch/x86/src/lib/include/{ => uapi/asm}/processor-flags.h (100%)
create mode 100644 compel/include/uapi/cpu.h
delete mode 100644 criu/arch/aarch64/include/asm/cpu.h
delete mode 100644 criu/arch/arm/include/asm/cpu.h
delete mode 100644 criu/arch/ppc64/include/asm/cpu.h
diff --git a/Makefile b/Makefile
index 7357dee7d16f..76bafa71ac32 100644
--- a/Makefile
+++ b/Makefile
@@ -228,9 +228,9 @@ $(SOCCR_A): |soccr/built-in.o
#
# But note that we're already included
# the nmk so we can reuse it there.
-criu/%: images/built-in.o compel/plugins/std.built-in.o compel/compel-host $(VERSION_HEADER) .FORCE
+criu/%: images/built-in.o compel/plugins/std.built-in.o compel/libcompel.a compel/compel-host $(VERSION_HEADER) .FORCE
$(Q) $(MAKE) $(build)=criu $@
-criu: images/built-in.o compel/plugins/std.built-in.o compel/compel-host $(SOCCR_A) $(VERSION_HEADER)
+criu: images/built-in.o compel/plugins/std.built-in.o compel/libcompel.a compel/compel-host $(SOCCR_A) $(VERSION_HEADER)
$(Q) $(MAKE) $(build)=criu all
.PHONY: criu
diff --git a/Makefile.compel b/Makefile.compel
index 88566501111a..366f604e9716 100644
--- a/Makefile.compel
+++ b/Makefile.compel
@@ -33,6 +33,7 @@ compel-uapi-links += $(SRC_DIR)/compel/include/asm
compel-deps += $(compel-uapi-links)
compel-deps += $(COMPEL_VERSION_HEADER)
compel-deps += $(CONFIG_HEADER)
+compel-deps += include/common/asm
#
# Compel itself.
diff --git a/compel/Makefile b/compel/Makefile
index f47d48805681..d421bc07891a 100644
--- a/compel/Makefile
+++ b/compel/Makefile
@@ -22,6 +22,8 @@ host-lib-y += src/lib/handle-elf.o
lib-y += src/lib/log.o
host-lib-y += src/lib/log.o
+lib-y += arch/$(ARCH)/src/lib/cpu.o
+
ifeq ($(ARCH),x86)
lib-y += src/lib/handle-elf-32.o
host-lib-y += src/lib/handle-elf-32.o
diff --git a/compel/arch/aarch64/src/lib/cpu.c b/compel/arch/aarch64/src/lib/cpu.c
new file mode 100644
index 000000000000..9e5d0d7fe4f9
--- /dev/null
+++ b/compel/arch/aarch64/src/lib/cpu.c
@@ -0,0 +1,28 @@
+#include <string.h>
+#include <stdbool.h>
+
+#include "uapi/compel/cpu.h"
+
+#include "common/bitops.h"
+
+#include "log.h"
+
+#undef LOG_PREFIX
+#define LOG_PREFIX "cpu: "
+
+static compel_cpuinfo_t rt_info;
+static bool rt_info_done = false;
+
+void compel_set_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { }
+void compel_clear_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { }
+int compel_test_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { return 0; }
+int compel_cpuid(compel_cpuinfo_t *info) { return 0; }
+
+bool cpu_has_feature(unsigned int feature)
+{
+ if (!rt_info_done) {
+ compel_cpuid(&rt_info);
+ rt_info_done = true;
+ }
+ return compel_test_cpu_cap(&rt_info, feature);
+}
diff --git a/compel/arch/aarch64/src/lib/include/uapi/asm/cpu.h b/compel/arch/aarch64/src/lib/include/uapi/asm/cpu.h
new file mode 100644
index 000000000000..c35460e15bde
--- /dev/null
+++ b/compel/arch/aarch64/src/lib/include/uapi/asm/cpu.h
@@ -0,0 +1,6 @@
+#ifndef UAPI_COMPEL_ASM_CPU_H__
+#define UAPI_COMPEL_ASM_CPU_H__
+
+typedef struct { } compel_cpuinfo_t;
+
+#endif /* UAPI_COMPEL_ASM_CPU_H__ */
diff --git a/compel/arch/aarch64/src/lib/include/uapi/asm/processor-flags.h b/compel/arch/aarch64/src/lib/include/uapi/asm/processor-flags.h
new file mode 100644
index 000000000000..15719184a3ba
--- /dev/null
+++ b/compel/arch/aarch64/src/lib/include/uapi/asm/processor-flags.h
@@ -0,0 +1,4 @@
+#ifndef UAPI_COMPEL_ASM_PROCESSOR_FLAGS_H__
+#define UAPI_COMPEL_ASM_PROCESSOR_FLAGS_H__
+
+#endif /* UAPI_COMPEL_ASM_PROCESSOR_FLAGS_H__ */
diff --git a/compel/arch/arm/src/lib/cpu.c b/compel/arch/arm/src/lib/cpu.c
new file mode 100644
index 000000000000..9e5d0d7fe4f9
--- /dev/null
+++ b/compel/arch/arm/src/lib/cpu.c
@@ -0,0 +1,28 @@
+#include <string.h>
+#include <stdbool.h>
+
+#include "uapi/compel/cpu.h"
+
+#include "common/bitops.h"
+
+#include "log.h"
+
+#undef LOG_PREFIX
+#define LOG_PREFIX "cpu: "
+
+static compel_cpuinfo_t rt_info;
+static bool rt_info_done = false;
+
+void compel_set_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { }
+void compel_clear_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { }
+int compel_test_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { return 0; }
+int compel_cpuid(compel_cpuinfo_t *info) { return 0; }
+
+bool cpu_has_feature(unsigned int feature)
+{
+ if (!rt_info_done) {
+ compel_cpuid(&rt_info);
+ rt_info_done = true;
+ }
+ return compel_test_cpu_cap(&rt_info, feature);
+}
diff --git a/compel/arch/arm/src/lib/include/uapi/asm/cpu.h b/compel/arch/arm/src/lib/include/uapi/asm/cpu.h
new file mode 100644
index 000000000000..c35460e15bde
--- /dev/null
+++ b/compel/arch/arm/src/lib/include/uapi/asm/cpu.h
@@ -0,0 +1,6 @@
+#ifndef UAPI_COMPEL_ASM_CPU_H__
+#define UAPI_COMPEL_ASM_CPU_H__
+
+typedef struct { } compel_cpuinfo_t;
+
+#endif /* UAPI_COMPEL_ASM_CPU_H__ */
diff --git a/compel/arch/arm/src/lib/include/processor-flags.h b/compel/arch/arm/src/lib/include/uapi/asm/processor-flags.h
similarity index 100%
rename from compel/arch/arm/src/lib/include/processor-flags.h
rename to compel/arch/arm/src/lib/include/uapi/asm/processor-flags.h
diff --git a/compel/arch/ppc64/src/lib/cpu.c b/compel/arch/ppc64/src/lib/cpu.c
new file mode 100644
index 000000000000..e324b80f9b21
--- /dev/null
+++ b/compel/arch/ppc64/src/lib/cpu.c
@@ -0,0 +1,42 @@
+#include <sys/auxv.h>
+#include <asm/cputable.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include "uapi/compel/cpu.h"
+
+#include "common/bitops.h"
+
+#include "log.h"
+
+#undef LOG_PREFIX
+#define LOG_PREFIX "cpu: "
+
+static compel_cpuinfo_t rt_info;
+static bool rt_info_done = false;
+
+void compel_set_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { }
+void compel_clear_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { }
+int compel_test_cpu_cap(compel_cpuinfo_t *info, unsigned int feature) { return 0; }
+
+int compel_cpuid(compel_cpuinfo_t *info)
+{
+ info->hwcap[0] = getauxval(AT_HWCAP);
+ info->hwcap[1] = getauxval(AT_HWCAP2);
+
+ if (!info->hwcap[0] || !info->hwcap[1]) {
+ pr_err("Can't read the hardware capabilities");
+ return -1;
+ }
+
+ return 0;
+}
+
+bool cpu_has_feature(unsigned int feature)
+{
+ if (!rt_info_done) {
+ compel_cpuid(&rt_info);
+ rt_info_done = true;
+ }
+ return compel_test_cpu_cap(&rt_info, feature);
+}
diff --git a/compel/arch/ppc64/src/lib/include/uapi/asm/cpu.h b/compel/arch/ppc64/src/lib/include/uapi/asm/cpu.h
new file mode 100644
index 000000000000..59925868c15a
--- /dev/null
+++ b/compel/arch/ppc64/src/lib/include/uapi/asm/cpu.h
@@ -0,0 +1,10 @@
+#ifndef UAPI_COMPEL_ASM_CPU_H__
+#define UAPI_COMPEL_ASM_CPU_H__
+
+#include <stdint.h>
+
+typedef struct {
+ uint64_t hwcap[2];
+} compel_cpuinfo_t;
+
+#endif /* UAPI_COMPEL_ASM_CPU_H__ */
diff --git a/compel/arch/ppc64/src/lib/include/uapi/asm/processor-flags.h b/compel/arch/ppc64/src/lib/include/uapi/asm/processor-flags.h
new file mode 100644
index 000000000000..15719184a3ba
--- /dev/null
+++ b/compel/arch/ppc64/src/lib/include/uapi/asm/processor-flags.h
@@ -0,0 +1,4 @@
+#ifndef UAPI_COMPEL_ASM_PROCESSOR_FLAGS_H__
+#define UAPI_COMPEL_ASM_PROCESSOR_FLAGS_H__
+
+#endif /* UAPI_COMPEL_ASM_PROCESSOR_FLAGS_H__ */
diff --git a/compel/arch/ppc64/src/lib/include/uapi/asm/processor.h b/compel/arch/ppc64/src/lib/include/uapi/asm/processor.h
new file mode 100644
index 000000000000..7376f8879a1a
--- /dev/null
+++ b/compel/arch/ppc64/src/lib/include/uapi/asm/processor.h
@@ -0,0 +1,4 @@
+#ifndef UAPI_COMPEL_ASM_PROCESSOR_H__
+#define UAPI_COMPEL_ASM_PROCESSOR_H__
+
+#endif /* UAPI_COMPEL_ASM_PROCESSOR_H__ */
diff --git a/compel/arch/x86/src/lib/cpu.c b/compel/arch/x86/src/lib/cpu.c
new file mode 100644
index 000000000000..7962a61c6ed1
--- /dev/null
+++ b/compel/arch/x86/src/lib/cpu.c
@@ -0,0 +1,189 @@
+#include <string.h>
+#include <stdbool.h>
+
+#include "uapi/compel/cpu.h"
+
+#include "common/bitops.h"
+#include "common/compiler.h"
+
+#include "log.h"
+
+#undef LOG_PREFIX
+#define LOG_PREFIX "cpu: "
+
+static compel_cpuinfo_t rt_info;
+static bool rt_info_done = false;
+
+void compel_set_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
+{
+ if (likely(feature < NCAPINTS_BITS))
+ set_bit(feature, (unsigned long *)c->x86_capability);
+}
+
+void compel_clear_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
+{
+ if (likely(feature < NCAPINTS_BITS))
+ clear_bit(feature, (unsigned long *)c->x86_capability);
+}
+
+int compel_test_cpu_cap(compel_cpuinfo_t *c, unsigned int feature)
+{
+ if (likely(feature < NCAPINTS_BITS))
+ return test_bit(feature, (unsigned long *)c->x86_capability);
+ return 0;
+}
+
+int compel_cpuid(compel_cpuinfo_t *c)
+{
+ /*
+ * See cpu_detect() in the kernel, also
+ * read cpuid specs not only from general
+ * SDM but for extended instructions set
+ * reference.
+ */
+
+ /* Get vendor name */
+ cpuid(0x00000000,
+ (unsigned int *)&c->cpuid_level,
+ (unsigned int *)&c->x86_vendor_id[0],
+ (unsigned int *)&c->x86_vendor_id[8],
+ (unsigned int *)&c->x86_vendor_id[4]);
+
+ if (!strcmp(c->x86_vendor_id, "GenuineIntel")) {
+ c->x86_vendor = X86_VENDOR_INTEL;
+ } else if (!strcmp(c->x86_vendor_id, "AuthenticAMD")) {
+ c->x86_vendor = X86_VENDOR_AMD;
+ } else {
+ pr_err("Unsupported CPU vendor %s\n",
+ c->x86_vendor_id);
+ return -1;
+ }
+
+ c->x86_family = 4;
+
+ /* Intel-defined flags: level 0x00000001 */
+ if (c->cpuid_level >= 0x00000001) {
+ uint32_t eax, ebx, ecx, edx;
+
+ cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
+ c->x86_family = (eax >> 8) & 0xf;
+ c->x86_model = (eax >> 4) & 0xf;
+ c->x86_mask = eax & 0xf;
+
+ if (c->x86_family == 0xf)
+ c->x86_family += (eax >> 20) & 0xff;
+ if (c->x86_family >= 0x6)
+ c->x86_model += ((eax >> 16) & 0xf) << 4;
+
+ c->x86_capability[0] = edx;
+ c->x86_capability[4] = ecx;
+ }
+
+ /* Additional Intel-defined flags: level 0x00000007 */
+ if (c->cpuid_level >= 0x00000007) {
+ uint32_t eax, ebx, ecx, edx;
+
+ cpuid_count(0x00000007, 0, &eax, &ebx, &ecx, &edx);
+ c->x86_capability[9] = ebx;
+ c->x86_capability[11] = ecx;
+ }
+
+ /* Extended state features: level 0x0000000d */
+ if (c->cpuid_level >= 0x0000000d) {
+ uint32_t eax, ebx, ecx, edx;
+
+ cpuid_count(0x0000000d, 1, &eax, &ebx, &ecx, &edx);
+ c->x86_capability[10] = eax;
+ }
+
+ /* AMD-defined flags: level 0x80000001 */
+ c->extended_cpuid_level = cpuid_eax(0x80000000);
+
+ if ((c->extended_cpuid_level & 0xffff0000) == 0x80000000) {
+ if (c->extended_cpuid_level >= 0x80000001) {
+ c->x86_capability[1] = cpuid_edx(0x80000001);
+ c->x86_capability[6] = cpuid_ecx(0x80000001);
+ }
+ }
+
+ /*
+ * We're don't care about scattered features for now,
+ * otherwise look into init_scattered_cpuid_features()
+ * in kernel.
+ */
+
+ if (c->extended_cpuid_level >= 0x80000004) {
+ unsigned int *v;
+ char *p, *q;
+ v = (unsigned int *)c->x86_model_id;
+ cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
+ cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
+ cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
+ c->x86_model_id[48] = 0;
+
+ /*
+ * Intel chips right-justify this string for some dumb reason;
+ * undo that brain damage:
+ */
+ p = q = &c->x86_model_id[0];
+ while (*p == ' ')
+ p++;
+ if (p != q) {
+ while (*p)
+ *q++ = *p++;
+ while (q <= &c->x86_model_id[48])
+ *q++ = '\0'; /* Zero-pad the rest */
+ }
+ }
+
+ /* On x86-64 NOP is always present */
+ compel_set_cpu_cap(c, X86_FEATURE_NOPL);
+
+ switch (c->x86_vendor) {
+ case X86_VENDOR_INTEL:
+ /*
+ * Strictly speaking we need to read MSR_IA32_MISC_ENABLE
+ * here but on ring3 it's impossible.
+ */
+ if (c->x86_family == 15) {
+ compel_clear_cpu_cap(c, X86_FEATURE_REP_GOOD);
+ compel_clear_cpu_cap(c, X86_FEATURE_ERMS);
+ } else if (c->x86_family == 6) {
+ /* On x86-64 rep is fine */
+ compel_set_cpu_cap(c, X86_FEATURE_REP_GOOD);
+ }
+
+ /* See filter_cpuid_features in kernel */
+ if ((int32_t)c->cpuid_level < (int32_t)0x0000000d)
+ compel_clear_cpu_cap(c, X86_FEATURE_XSAVE);
+ break;
+ case X86_VENDOR_AMD:
+ /*
+ * Bit 31 in normal CPUID used for nonstandard 3DNow ID;
+ * 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway
+ */
+ compel_clear_cpu_cap(c, 0 * 32 + 31);
+ if (c->x86_family >= 0x10)
+ compel_set_cpu_cap(c, X86_FEATURE_REP_GOOD);
+ if (c->x86_family == 0xf) {
+ uint32_t level;
+
+ /* On C+ stepping K8 rep microcode works well for copy/memset */
+ level = cpuid_eax(1);
+ if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
+ compel_set_cpu_cap(c, X86_FEATURE_REP_GOOD);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+bool cpu_has_feature(unsigned int feature)
+{
+ if (!rt_info_done) {
+ compel_cpuid(&rt_info);
+ rt_info_done = true;
+ }
+ return compel_test_cpu_cap(&rt_info, feature);
+}
diff --git a/criu/arch/x86/include/asm/cpu.h b/compel/arch/x86/src/lib/include/uapi/asm/cpu.h
similarity index 95%
rename from criu/arch/x86/include/asm/cpu.h
rename to compel/arch/x86/src/lib/include/uapi/asm/cpu.h
index 6f49229d6396..f79ace1fcf58 100644
--- a/criu/arch/x86/include/asm/cpu.h
+++ b/compel/arch/x86/src/lib/include/uapi/asm/cpu.h
@@ -1,7 +1,7 @@
#ifndef __CR_ASM_CPU_H__
#define __CR_ASM_CPU_H__
-#include "asm/types.h"
+#include <stdint.h>
/*
* Adopted from linux kernel and enhanced from Intel/AMD manuals.
@@ -176,8 +176,6 @@ static inline unsigned int cpuid_edx(unsigned int op)
return edx;
}
-#define X86_FEATURE_VERSION 1
-
enum {
X86_VENDOR_INTEL = 0,
X86_VENDOR_AMD = 1,
@@ -186,22 +184,17 @@ enum {
};
struct cpuinfo_x86 {
- u8 x86_family;
- u8 x86_vendor;
- u8 x86_model;
- u8 x86_mask;
- u32 x86_capability[NCAPINTS];
- u32 extended_cpuid_level;
+ uint8_t x86_family;
+ uint8_t x86_vendor;
+ uint8_t x86_model;
+ uint8_t x86_mask;
+ uint32_t x86_capability[NCAPINTS];
+ uint32_t extended_cpuid_level;
int cpuid_level;
char x86_vendor_id[16];
char x86_model_id[64];
};
-extern bool cpu_has_feature(unsigned int feature);
-extern int cpu_init(void);
-extern int cpu_dump_cpuinfo(void);
-extern int cpu_validate_cpuinfo(void);
-extern int cpuinfo_dump(void);
-extern int cpuinfo_check(void);
+typedef struct cpuinfo_x86 compel_cpuinfo_t;
-#endif /* __CR_CPU_H__ */
+#endif /* __CR_ASM_CPU_H__ */
diff --git a/compel/arch/x86/src/lib/include/processor-flags.h b/compel/arch/x86/src/lib/include/uapi/asm/processor-flags.h
similarity index 100%
rename from compel/arch/x86/src/lib/include/processor-flags.h
rename to compel/arch/x86/src/lib/include/uapi/asm/processor-flags.h
diff --git a/compel/include/uapi/cpu.h b/compel/include/uapi/cpu.h
new file mode 100644
index 000000000000..662883bc941d
--- /dev/null
+++ b/compel/include/uapi/cpu.h
@@ -0,0 +1,14 @@
+#ifndef UAPI_COMPEL_CPU_H__
+#define UAPI_COMPEL_CPU_H__
+
+#include <stdbool.h>
+
+#include <compel/asm/cpu.h>
+
+extern void compel_set_cpu_cap(compel_cpuinfo_t *info, unsigned int feature);
+extern void compel_clear_cpu_cap(compel_cpuinfo_t *info, unsigned int feature);
+extern int compel_test_cpu_cap(compel_cpuinfo_t *info, unsigned int feature);
+extern int compel_cpuid(compel_cpuinfo_t *info);
+extern bool cpu_has_feature(unsigned int feature);
+
+#endif /* UAPI_COMPEL_CPU_H__ */
diff --git a/criu/Makefile b/criu/Makefile
index f158325bf7e1..9cf07f28ea61 100644
--- a/criu/Makefile
+++ b/criu/Makefile
@@ -72,6 +72,7 @@ PROGRAM-BUILTINS += criu/pie/native.lib.a
PROGRAM-BUILTINS += images/built-in.o
PROGRAM-BUILTINS += $(obj)/built-in.o
PROGRAM-BUILTINS += $(ARCH-LIB)
+PROGRAM-BUILTINS += compel/libcompel.a
$(obj)/built-in.o: pie
$(Q) $(MAKE) $(call build-as,Makefile.crtools,criu) all
diff --git a/criu/arch/aarch64/cpu.c b/criu/arch/aarch64/cpu.c
index 040fe14fcfb7..34313fb1569b 100644
--- a/criu/arch/aarch64/cpu.c
+++ b/criu/arch/aarch64/cpu.c
@@ -4,11 +4,6 @@
#include <errno.h>
#include "cpu.h"
-bool cpu_has_feature(unsigned int feature)
-{
- return false;
-}
-
int cpu_init(void)
{
return 0;
diff --git a/criu/arch/aarch64/crtools.c b/criu/arch/aarch64/crtools.c
index 8e4f48656819..fd34484dfe5a 100644
--- a/criu/arch/aarch64/crtools.c
+++ b/criu/arch/aarch64/crtools.c
@@ -4,6 +4,8 @@
#include <linux/elf.h>
#include "types.h"
+#include <compel/asm/processor-flags.h>
+
#include "asm/restorer.h"
#include "common/compiler.h"
#include "ptrace.h"
diff --git a/criu/arch/aarch64/include/asm/cpu.h b/criu/arch/aarch64/include/asm/cpu.h
deleted file mode 100644
index 59118c211d10..000000000000
--- a/criu/arch/aarch64/include/asm/cpu.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <stdbool.h>
diff --git a/criu/arch/arm/cpu.c b/criu/arch/arm/cpu.c
index 040fe14fcfb7..34313fb1569b 100644
--- a/criu/arch/arm/cpu.c
+++ b/criu/arch/arm/cpu.c
@@ -4,11 +4,6 @@
#include <errno.h>
#include "cpu.h"
-bool cpu_has_feature(unsigned int feature)
-{
- return false;
-}
-
int cpu_init(void)
{
return 0;
diff --git a/criu/arch/arm/crtools.c b/criu/arch/arm/crtools.c
index d0576d5ae7e3..07c6473f5bdb 100644
--- a/criu/arch/arm/crtools.c
+++ b/criu/arch/arm/crtools.c
@@ -2,6 +2,8 @@
#include <unistd.h>
#include "types.h"
+#include <compel/asm/processor-flags.h>
+
#include "asm/restorer.h"
#include "common/compiler.h"
#include "asm/dump.h"
diff --git a/criu/arch/arm/include/asm/cpu.h b/criu/arch/arm/include/asm/cpu.h
deleted file mode 100644
index 59118c211d10..000000000000
--- a/criu/arch/arm/include/asm/cpu.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <stdbool.h>
diff --git a/criu/arch/ppc64/cpu.c b/criu/arch/ppc64/cpu.c
index 222bc62d12bf..aecba78014d8 100644
--- a/criu/arch/ppc64/cpu.c
+++ b/criu/arch/ppc64/cpu.c
@@ -6,7 +6,6 @@
#include <asm/cputable.h>
#include "asm/types.h"
-#include "asm/cpu.h"
#include "cr_options.h"
#include "image.h"
@@ -17,7 +16,7 @@
#include "protobuf.h"
#include "images/cpuinfo.pb-c.h"
-static uint64_t hwcap[2];
+static compel_cpuinfo_t rt_cpuinfo;
#ifdef __LITTLE_ENDIAN__
#define CURRENT_ENDIANNESS CPUINFO_PPC64_ENTRY__ENDIANNESS__LITTLEENDIAN
@@ -27,14 +26,7 @@ static uint64_t hwcap[2];
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;
+ return compel_cpuid(&rt_cpuinfo);
}
int cpu_dump_cpuinfo(void)
@@ -54,7 +46,7 @@ int cpu_dump_cpuinfo(void)
cpu_ppc64_info.endian = CURRENT_ENDIANNESS;
cpu_ppc64_info.n_hwcap = 2;
- cpu_ppc64_info.hwcap = hwcap;
+ cpu_ppc64_info.hwcap = rt_cpuinfo.hwcap;
ret = pb_write_one(img, &cpu_info, PB_CPUINFO);
@@ -92,7 +84,8 @@ int cpu_validate_cpuinfo(void)
}
#define CHECK_FEATURE(s,f) do { \
- if ((cpu_ppc64_entry->hwcap[s] & f) && !(hwcap[s] & f)) { \
+ if ((cpu_ppc64_entry->hwcap[s] & f) && \
+ !(rt_cpuinfo.hwcap[s] & f)) { \
pr_err("CPU Feature %s required by image " \
"is not supported on host.\n", #f); \
goto error; \
diff --git a/criu/arch/ppc64/include/asm/cpu.h b/criu/arch/ppc64/include/asm/cpu.h
deleted file mode 100644
index 59118c211d10..000000000000
--- a/criu/arch/ppc64/include/asm/cpu.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <stdbool.h>
diff --git a/criu/arch/x86/cpu.c b/criu/arch/x86/cpu.c
index 89fc86029454..15b75111a7f9 100644
--- a/criu/arch/x86/cpu.c
+++ b/criu/arch/x86/cpu.c
@@ -10,6 +10,7 @@
#include "asm/types.h"
#include "asm/cpu.h"
#include "asm/fpu.h"
+#include <compel/cpu.h>
#include "common/compiler.h"
@@ -26,181 +27,11 @@
#undef LOG_PREFIX
#define LOG_PREFIX "cpu: "
-static struct cpuinfo_x86 rt_cpu_info;
-
-static void set_cpu_cap(struct cpuinfo_x86 *c, unsigned int feature)
-{
- if (likely(feature < NCAPINTS_BITS))
- set_bit(feature, (unsigned long *)c->x86_capability);
-}
-
-static void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int feature)
-{
- if (likely(feature < NCAPINTS_BITS))
- clear_bit(feature, (unsigned long *)c->x86_capability);
-}
-
-static int test_cpu_cap(struct cpuinfo_x86 *c, unsigned int feature)
-{
- if (likely(feature < NCAPINTS_BITS))
- return test_bit(feature, (unsigned long *)c->x86_capability);
- return 0;
-}
-
-bool cpu_has_feature(unsigned int feature)
-{
- return test_cpu_cap(&rt_cpu_info, feature);
-}
-
-static int cpu_init_cpuid(struct cpuinfo_x86 *c)
-{
- /*
- * See cpu_detect() in the kernel, also
- * read cpuid specs not only from general
- * SDM but for extended instructions set
- * reference.
- */
-
- /* Get vendor name */
- cpuid(0x00000000,
- (unsigned int *)&c->cpuid_level,
- (unsigned int *)&c->x86_vendor_id[0],
- (unsigned int *)&c->x86_vendor_id[8],
- (unsigned int *)&c->x86_vendor_id[4]);
-
- if (!strcmp(c->x86_vendor_id, "GenuineIntel")) {
- c->x86_vendor = X86_VENDOR_INTEL;
- } else if (!strcmp(c->x86_vendor_id, "AuthenticAMD")) {
- c->x86_vendor = X86_VENDOR_AMD;
- } else {
- pr_err("Unsupported CPU vendor %s\n",
- c->x86_vendor_id);
- return -1;
- }
-
- c->x86_family = 4;
-
- /* Intel-defined flags: level 0x00000001 */
- if (c->cpuid_level >= 0x00000001) {
- u32 eax, ebx, ecx, edx;
-
- cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
- c->x86_family = (eax >> 8) & 0xf;
- c->x86_model = (eax >> 4) & 0xf;
- c->x86_mask = eax & 0xf;
-
- if (c->x86_family == 0xf)
- c->x86_family += (eax >> 20) & 0xff;
- if (c->x86_family >= 0x6)
- c->x86_model += ((eax >> 16) & 0xf) << 4;
-
- c->x86_capability[0] = edx;
- c->x86_capability[4] = ecx;
- }
-
- /* Additional Intel-defined flags: level 0x00000007 */
- if (c->cpuid_level >= 0x00000007) {
- u32 eax, ebx, ecx, edx;
-
- cpuid_count(0x00000007, 0, &eax, &ebx, &ecx, &edx);
- c->x86_capability[9] = ebx;
- c->x86_capability[11] = ecx;
- }
-
- /* Extended state features: level 0x0000000d */
- if (c->cpuid_level >= 0x0000000d) {
- u32 eax, ebx, ecx, edx;
-
- cpuid_count(0x0000000d, 1, &eax, &ebx, &ecx, &edx);
- c->x86_capability[10] = eax;
- }
-
- /* AMD-defined flags: level 0x80000001 */
- c->extended_cpuid_level = cpuid_eax(0x80000000);
-
- if ((c->extended_cpuid_level & 0xffff0000) == 0x80000000) {
- if (c->extended_cpuid_level >= 0x80000001) {
- c->x86_capability[1] = cpuid_edx(0x80000001);
- c->x86_capability[6] = cpuid_ecx(0x80000001);
- }
- }
-
- /*
- * We're don't care about scattered features for now,
- * otherwise look into init_scattered_cpuid_features()
- * in kernel.
- */
-
- if (c->extended_cpuid_level >= 0x80000004) {
- unsigned int *v;
- char *p, *q;
- v = (unsigned int *)c->x86_model_id;
- cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
- cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
- cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
- c->x86_model_id[48] = 0;
-
- /*
- * Intel chips right-justify this string for some dumb reason;
- * undo that brain damage:
- */
- p = q = &c->x86_model_id[0];
- while (*p == ' ')
- p++;
- if (p != q) {
- while (*p)
- *q++ = *p++;
- while (q <= &c->x86_model_id[48])
- *q++ = '\0'; /* Zero-pad the rest */
- }
- }
-
- /* On x86-64 NOP is always present */
- set_cpu_cap(c, X86_FEATURE_NOPL);
-
- switch (c->x86_vendor) {
- case X86_VENDOR_INTEL:
- /*
- * Strictly speaking we need to read MSR_IA32_MISC_ENABLE
- * here but on ring3 it's impossible.
- */
- if (c->x86_family == 15) {
- clear_cpu_cap(c, X86_FEATURE_REP_GOOD);
- clear_cpu_cap(c, X86_FEATURE_ERMS);
- } else if (c->x86_family == 6) {
- /* On x86-64 rep is fine */
- set_cpu_cap(c, X86_FEATURE_REP_GOOD);
- }
-
- /* See filter_cpuid_features in kernel */
- if ((s32)c->cpuid_level < (s32)0x0000000d)
- clear_cpu_cap(c, X86_FEATURE_XSAVE);
- break;
- case X86_VENDOR_AMD:
- /*
- * Bit 31 in normal CPUID used for nonstandard 3DNow ID;
- * 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway
- */
- clear_cpu_cap(c, 0 * 32 + 31);
- if (c->x86_family >= 0x10)
- set_cpu_cap(c, X86_FEATURE_REP_GOOD);
- if (c->x86_family == 0xf) {
- u32 level;
-
- /* On C+ stepping K8 rep microcode works well for copy/memset */
- level = cpuid_eax(1);
- if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
- set_cpu_cap(c, X86_FEATURE_REP_GOOD);
- }
- break;
- }
-
- return 0;
-}
+static compel_cpuinfo_t rt_cpu_info;
int cpu_init(void)
{
- if (cpu_init_cpuid(&rt_cpu_info))
+ if (compel_cpuid(&rt_cpu_info))
return -1;
BUILD_BUG_ON(sizeof(struct xsave_struct) != XSAVE_SIZE);
diff --git a/criu/arch/x86/infect.c b/criu/arch/x86/infect.c
index 748be1cd9e18..cf92cd551bbd 100644
--- a/criu/arch/x86/infect.c
+++ b/criu/arch/x86/infect.c
@@ -9,7 +9,8 @@
#include "asm/cpu.h"
#include "kerndat.h"
-#include "compel/include/asm/processor-flags.h"
+#include <compel/asm/processor-flags.h>
+#include <compel/cpu.h>
#include "compel/include/errno.h"
#include <compel/plugins/std/syscall-codes.h>
#include <compel/plugins/std/syscall.h>
diff --git a/criu/include/cpu.h b/criu/include/cpu.h
index e94525a9e780..e30696790e72 100644
--- a/criu/include/cpu.h
+++ b/criu/include/cpu.h
@@ -1,9 +1,8 @@
#ifndef __CR_CPU_H__
#define __CR_CPU_H__
-#include "asm/cpu.h"
+#include <compel/cpu.h>
-extern bool cpu_has_feature(unsigned int feature);
extern int cpu_init(void);
extern int cpu_dump_cpuinfo(void);
extern int cpu_validate_cpuinfo(void);
--
2.7.4
More information about the CRIU
mailing list