[CRIU] [PATCH 18/22] compel: Move in cpu interface
Cyrill Gorcunov
gorcunov at openvz.org
Wed Oct 19 12:21:33 PDT 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>
---
compel/Makefile | 19 +++
compel/arch/aarch64/src/lib/cpu.c | 28 +++
.../arch/aarch64/src/lib/include/compel/asm/cpu.h | 6 +
.../src/lib/include/compel/asm/processor-flags.h | 4 +
.../aarch64/src/lib/include/compel/asm/processor.h | 4 +
compel/arch/arm/src/lib/cpu.c | 28 +++
compel/arch/arm/src/lib/include/compel/asm/cpu.h | 6 +
.../src/lib/include/compel}/asm/processor-flags.h | 6 +-
.../arm/src/lib/include/compel}/asm/processor.h | 6 +-
compel/arch/ppc64/src/lib/cpu.c | 42 +++++
compel/arch/ppc64/src/lib/include/compel/asm/cpu.h | 10 ++
.../src/lib/include/compel/asm/processor-flags.h | 4 +
.../ppc64/src/lib/include/compel/asm/processor.h | 4 +
compel/arch/x86/src/lib/cpu.c | 189 +++++++++++++++++++++
.../arch/x86/src/lib/include/compel}/asm/cpu.h | 29 ++--
.../src/lib/include/compel}/asm/processor-flags.h | 6 +-
.../x86/src/lib/include/compel/asm/processor.h | 4 +
compel/include/uapi/compel/cpu.h | 14 ++
criu/Makefile | 1 +
criu/arch/aarch64/cpu.c | 5 -
criu/arch/aarch64/crtools.c | 3 +-
criu/arch/aarch64/include/asm/cpu.h | 1 -
criu/arch/aarch64/include/asm/processor-flags.h | 4 -
criu/arch/arm/cpu.c | 5 -
criu/arch/arm/crtools.c | 3 +-
criu/arch/arm/include/asm/cpu.h | 1 -
criu/arch/ppc64/cpu.c | 17 +-
criu/arch/ppc64/include/asm/cpu.h | 1 -
criu/arch/ppc64/include/asm/processor-flags.h | 4 -
criu/arch/x86/cpu.c | 177 +------------------
criu/arch/x86/crtools.c | 2 +-
criu/arch/x86/infect.c | 2 +-
criu/include/cpu.h | 3 +-
criu/parasite-syscall.c | 2 +-
34 files changed, 400 insertions(+), 240 deletions(-)
create mode 100644 compel/arch/aarch64/src/lib/cpu.c
create mode 100644 compel/arch/aarch64/src/lib/include/compel/asm/cpu.h
create mode 100644 compel/arch/aarch64/src/lib/include/compel/asm/processor-flags.h
create mode 100644 compel/arch/aarch64/src/lib/include/compel/asm/processor.h
create mode 100644 compel/arch/arm/src/lib/cpu.c
create mode 100644 compel/arch/arm/src/lib/include/compel/asm/cpu.h
rename {criu/arch/arm/include => compel/arch/arm/src/lib/include/compel}/asm/processor-flags.h (90%)
rename {criu/arch/arm/include => compel/arch/arm/src/lib/include/compel}/asm/processor.h (81%)
create mode 100644 compel/arch/ppc64/src/lib/cpu.c
create mode 100644 compel/arch/ppc64/src/lib/include/compel/asm/cpu.h
create mode 100644 compel/arch/ppc64/src/lib/include/compel/asm/processor-flags.h
create mode 100644 compel/arch/ppc64/src/lib/include/compel/asm/processor.h
create mode 100644 compel/arch/x86/src/lib/cpu.c
rename {criu/arch/x86/include => compel/arch/x86/src/lib/include/compel}/asm/cpu.h (94%)
rename {criu/arch/x86/include => compel/arch/x86/src/lib/include/compel}/asm/processor-flags.h (88%)
create mode 100644 compel/arch/x86/src/lib/include/compel/asm/processor.h
create mode 100644 compel/include/uapi/compel/cpu.h
delete mode 100644 criu/arch/aarch64/include/asm/cpu.h
delete mode 100644 criu/arch/aarch64/include/asm/processor-flags.h
delete mode 100644 criu/arch/arm/include/asm/cpu.h
delete mode 100644 criu/arch/ppc64/include/asm/cpu.h
delete mode 100644 criu/arch/ppc64/include/asm/processor-flags.h
diff --git a/compel/Makefile b/compel/Makefile
index bab15489deff..3fa47455d3fb 100644
--- a/compel/Makefile
+++ b/compel/Makefile
@@ -25,10 +25,29 @@ host-lib-y += src/lib/handle-elf.o
lib-y += src/lib/fds.o
lib-y += src/lib/argv.o
lib-y += src/lib/compel.o
+lib-y += arch/$(ARCH)/src/lib/cpu.o
#
# This requires arch specific header to
# be generated into uapi
+$(obj)/include/uapi/compel/asm/cpu.h: $(obj)/arch/$(ARCH)/src/lib/include/compel/asm/cpu.h
+ $(call msg-gen, $@)
+ $(Q) cp $^ $@
+cleanup-y += $(obj)/include/uapi/compel/asm/cpu.h
+headers-y += $(obj)/include/uapi/compel/asm/cpu.h
+
+$(obj)/include/uapi/compel/asm/processor-flags.h: $(obj)/arch/$(ARCH)/src/lib/include/compel/asm/processor-flags.h
+ $(call msg-gen, $@)
+ $(Q) cp $^ $@
+cleanup-y += $(obj)/include/uapi/compel/asm/processor-flags.h
+headers-y += $(obj)/include/uapi/compel/asm/processor-flags.h
+
+$(obj)/include/uapi/compel/asm/processor.h: $(obj)/arch/$(ARCH)/src/lib/include/compel/asm/processor.h
+ $(call msg-gen, $@)
+ $(Q) cp $^ $@
+cleanup-y += $(obj)/include/uapi/compel/asm/processor.h
+headers-y += $(obj)/include/uapi/compel/asm/processor.h
+
$(obj)/include/uapi/compel/asm/bitops.h: $(obj)/arch/$(ARCH)/src/lib/include/compel/asm/bitops.h
$(call msg-gen, $@)
$(Q) cp $^ $@
diff --git a/compel/arch/aarch64/src/lib/cpu.c b/compel/arch/aarch64/src/lib/cpu.c
new file mode 100644
index 000000000000..ddfcba02bba5
--- /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 "asm/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/compel/asm/cpu.h b/compel/arch/aarch64/src/lib/include/compel/asm/cpu.h
new file mode 100644
index 000000000000..c35460e15bde
--- /dev/null
+++ b/compel/arch/aarch64/src/lib/include/compel/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/compel/asm/processor-flags.h b/compel/arch/aarch64/src/lib/include/compel/asm/processor-flags.h
new file mode 100644
index 000000000000..15719184a3ba
--- /dev/null
+++ b/compel/arch/aarch64/src/lib/include/compel/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/aarch64/src/lib/include/compel/asm/processor.h b/compel/arch/aarch64/src/lib/include/compel/asm/processor.h
new file mode 100644
index 000000000000..7376f8879a1a
--- /dev/null
+++ b/compel/arch/aarch64/src/lib/include/compel/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/arm/src/lib/cpu.c b/compel/arch/arm/src/lib/cpu.c
new file mode 100644
index 000000000000..ddfcba02bba5
--- /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 "asm/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/compel/asm/cpu.h b/compel/arch/arm/src/lib/include/compel/asm/cpu.h
new file mode 100644
index 000000000000..c35460e15bde
--- /dev/null
+++ b/compel/arch/arm/src/lib/include/compel/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/criu/arch/arm/include/asm/processor-flags.h b/compel/arch/arm/src/lib/include/compel/asm/processor-flags.h
similarity index 90%
rename from criu/arch/arm/include/asm/processor-flags.h
rename to compel/arch/arm/src/lib/include/compel/asm/processor-flags.h
index fc00a9e64a2e..c772a911f39b 100644
--- a/criu/arch/arm/include/asm/processor-flags.h
+++ b/compel/arch/arm/src/lib/include/compel/asm/processor-flags.h
@@ -1,5 +1,5 @@
-#ifndef __CR_PROCESSOR_FLAGS_H__
-#define __CR_PROCESSOR_FLAGS_H__
+#ifndef UAPI_COMPEL_ASM_PROCESSOR_FLAGS_H__
+#define UAPI_COMPEL_ASM_PROCESSOR_FLAGS_H__
/* Copied from the Linux kernel header arch/arm/include/uapi/asm/ptrace.h */
@@ -39,4 +39,4 @@
#define PSR_x 0x0000ff00 /* Extension */
#define PSR_c 0x000000ff /* Control */
-#endif
+#endif /* UAPI_COMPEL_ASM_PROCESSOR_FLAGS_H__ */
diff --git a/criu/arch/arm/include/asm/processor.h b/compel/arch/arm/src/lib/include/compel/asm/processor.h
similarity index 81%
rename from criu/arch/arm/include/asm/processor.h
rename to compel/arch/arm/src/lib/include/compel/asm/processor.h
index a390cfd322ec..d5c0077448f5 100644
--- a/criu/arch/arm/include/asm/processor.h
+++ b/compel/arch/arm/src/lib/include/compel/asm/processor.h
@@ -1,5 +1,5 @@
-#ifndef __CR_PROCESSOR_H__
-#define __CR_PROCESSOR_H__
+#ifndef UAPI_COMPEL_ASM_PROCESSOR_H__
+#define UAPI_COMPEL_ASM_PROCESSOR_H__
/* Copied from linux kernel arch/arm/include/asm/unified.h */
@@ -25,4 +25,4 @@ static inline void prefetchw(const void *ptr)
:: "p" (ptr));
}
-#endif /* __CR_PROCESSOR_H__ */
+#endif /* UAPI_COMPEL_ASM_PROCESSOR_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..eb3798489a91
--- /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 "asm/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/compel/asm/cpu.h b/compel/arch/ppc64/src/lib/include/compel/asm/cpu.h
new file mode 100644
index 000000000000..59925868c15a
--- /dev/null
+++ b/compel/arch/ppc64/src/lib/include/compel/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/compel/asm/processor-flags.h b/compel/arch/ppc64/src/lib/include/compel/asm/processor-flags.h
new file mode 100644
index 000000000000..15719184a3ba
--- /dev/null
+++ b/compel/arch/ppc64/src/lib/include/compel/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/compel/asm/processor.h b/compel/arch/ppc64/src/lib/include/compel/asm/processor.h
new file mode 100644
index 000000000000..7376f8879a1a
--- /dev/null
+++ b/compel/arch/ppc64/src/lib/include/compel/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..7e379d04d0f3
--- /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 "asm/bitops.h"
+
+#include "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/compel/asm/cpu.h
similarity index 94%
rename from criu/arch/x86/include/asm/cpu.h
rename to compel/arch/x86/src/lib/include/compel/asm/cpu.h
index 6f49229d6396..ae5cee230cff 100644
--- a/criu/arch/x86/include/asm/cpu.h
+++ b/compel/arch/x86/src/lib/include/compel/asm/cpu.h
@@ -1,7 +1,7 @@
-#ifndef __CR_ASM_CPU_H__
-#define __CR_ASM_CPU_H__
+#ifndef UAPI_COMPEL_ASM_CPU_H__
+#define UAPI_COMPEL_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 /* UAPI_COMPEL_ASM_CPU_H__ */
diff --git a/criu/arch/x86/include/asm/processor-flags.h b/compel/arch/x86/src/lib/include/compel/asm/processor-flags.h
similarity index 88%
rename from criu/arch/x86/include/asm/processor-flags.h
rename to compel/arch/x86/src/lib/include/compel/asm/processor-flags.h
index 9f1bccdbece8..dd33dbfd17b0 100644
--- a/criu/arch/x86/include/asm/processor-flags.h
+++ b/compel/arch/x86/src/lib/include/compel/asm/processor-flags.h
@@ -1,5 +1,5 @@
-#ifndef __CR_PROCESSOR_FLAGS_H__
-#define __CR_PROCESSOR_FLAGS_H__
+#ifndef UAPI_COMPEL_ASM_PROCESSOR_FLAGS_H__
+#define UAPI_COMPEL_ASM_PROCESSOR_FLAGS_H__
/* Taken from linux kernel headers */
@@ -25,4 +25,4 @@
#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
-#endif /* __CR_PROCESSOR_FLAGS_H__ */
+#endif /* UAPI_COMPEL_ASM_PROCESSOR_FLAGS_H__ */
diff --git a/compel/arch/x86/src/lib/include/compel/asm/processor.h b/compel/arch/x86/src/lib/include/compel/asm/processor.h
new file mode 100644
index 000000000000..7376f8879a1a
--- /dev/null
+++ b/compel/arch/x86/src/lib/include/compel/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/include/uapi/compel/cpu.h b/compel/include/uapi/compel/cpu.h
new file mode 100644
index 000000000000..662883bc941d
--- /dev/null
+++ b/compel/include/uapi/compel/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 e9cc9fd626b7..45875ade4901 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 c61df4ae5758..c1da5ef01c2b 100644
--- a/criu/arch/aarch64/crtools.c
+++ b/criu/arch/aarch64/crtools.c
@@ -3,11 +3,12 @@
#include <linux/elf.h>
+#include <compel/asm/processor-flags.h>
+
#include "asm/types.h"
#include "asm/restorer.h"
#include "compiler.h"
#include "ptrace.h"
-#include "asm/processor-flags.h"
#include "asm/dump.h"
#include "protobuf.h"
#include "images/core.pb-c.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/aarch64/include/asm/processor-flags.h b/criu/arch/aarch64/include/asm/processor-flags.h
deleted file mode 100644
index c1888af36fa0..000000000000
--- a/criu/arch/aarch64/include/asm/processor-flags.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __CR_PROCESSOR_FLAGS_H__
-#define __CR_PROCESSOR_FLAGS_H__
-
-#endif
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 4caa417f304e..5b6469d59407 100644
--- a/criu/arch/arm/crtools.c
+++ b/criu/arch/arm/crtools.c
@@ -1,12 +1,13 @@
#include <string.h>
#include <unistd.h>
+#include <compel/asm/processor-flags.h>
+
#include "asm/types.h"
#include "asm/restorer.h"
#include "asm/dump.h"
#include "compiler.h"
#include "ptrace.h"
-#include "asm/processor-flags.h"
#include "protobuf.h"
#include "images/core.pb-c.h"
#include "images/creds.pb-c.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/ppc64/include/asm/processor-flags.h b/criu/arch/ppc64/include/asm/processor-flags.h
deleted file mode 100644
index c1888af36fa0..000000000000
--- a/criu/arch/ppc64/include/asm/processor-flags.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __CR_PROCESSOR_FLAGS_H__
-#define __CR_PROCESSOR_FLAGS_H__
-
-#endif
diff --git a/criu/arch/x86/cpu.c b/criu/arch/x86/cpu.c
index df77f30c9505..6b8ed155994e 100644
--- a/criu/arch/x86/cpu.c
+++ b/criu/arch/x86/cpu.c
@@ -7,9 +7,10 @@
#include <sys/types.h>
#include <compel/asm/bitops.h>
+#include <compel/asm/fpu.h>
+#include <compel/cpu.h>
#include "asm/types.h"
-#include "asm/cpu.h"
#include "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/crtools.c b/criu/arch/x86/crtools.c
index 49fe9f6c77bd..98b665354d42 100644
--- a/criu/arch/x86/crtools.c
+++ b/criu/arch/x86/crtools.c
@@ -7,8 +7,8 @@
#include <sys/auxv.h>
#include <compel/plugins/std/syscall-codes.h>
+#include <compel/asm/processor-flags.h>
-#include "asm/processor-flags.h"
#include "asm/parasite-syscall.h"
#include "asm/restorer.h"
#include "asm/types.h"
diff --git a/criu/arch/x86/infect.c b/criu/arch/x86/infect.c
index fa07698068a8..70423f6e34c3 100644
--- a/criu/arch/x86/infect.c
+++ b/criu/arch/x86/infect.c
@@ -5,12 +5,12 @@
#include <sys/mman.h>
#include <compel/plugins/std/syscall-codes.h>
+#include <compel/cpu.h>
#include "asm/parasite-syscall.h"
#include "err.h"
#include "asm/types.h"
#include "errno.h"
-#include "asm/cpu.h"
#include "parasite-syscall.h"
#include "infect.h"
#include "infect-priv.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);
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index b831a7834f2b..09c9c895afc7 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -6,6 +6,7 @@
#include <sys/mman.h>
#include <compel/plugins/std/syscall-codes.h>
+#include <compel/asm/processor-flags.h>
#include "protobuf.h"
#include "images/sa.pb-c.h"
@@ -16,7 +17,6 @@
#include "imgset.h"
#include "ptrace.h"
-#include "asm/processor-flags.h"
#include "parasite-syscall.h"
#include "parasite.h"
#include "crtools.h"
--
2.7.4
More information about the CRIU
mailing list