mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +00:00
cpuinfo: x86 -- Add dump and validation of cpuinfo image, v2
On Wed, Oct 01, 2014 at 04:57:40PM +0400, Pavel Emelyanov wrote: > On 10/01/2014 01:07 AM, Cyrill Gorcunov wrote: > > On Tue, Sep 30, 2014 at 09:18:53PM +0400, Cyrill Gorcunov wrote: > >> If a user requested criu to dump cpuinfo image then we > >> write one on dump and verify on restore. At the moment > >> we require all cpu feature bits to match the destination > >> cpu in a sake of simplicity, but in future we need deps > >> engine which would filer out bits and test if cpu we're > >> restoring on is more capable than one we were dumping at > >> allowing to proceed restore procedure. > >> > >> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> > > > > Updated to new img format Something like attached? >From 59272a9514311e6736cddee08d5f88aa95d49189 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov <gorcunov@openvz.org> Date: Thu, 25 Sep 2014 16:04:10 +0400 Subject: [PATCH] cpuinfo: x86 -- Add dump and validation of cpuinfo image If a user requested criu to dump cpuinfo image then we write one on dump and verify on restore. At the moment we require all cpu feature bits to match the destination cpu in a sake of simplicity, but in future we need deps engine which would filer out bits and test if cpu we're restoring on is more capable than one we were dumping at allowing to proceed restore procedure. Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
e07b4a0e7a
commit
87273ccdb8
@@ -12,3 +12,13 @@ int cpu_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_dump_cpuinfo(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_validate_cpuinfo(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@@ -12,3 +12,13 @@ int cpu_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_dump_cpuinfo(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_validate_cpuinfo(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
135
arch/x86/cpu.c
135
arch/x86/cpu.c
@@ -13,12 +13,16 @@
|
||||
|
||||
#include "compiler.h"
|
||||
|
||||
#include "cr_options.h"
|
||||
#include "proc_parse.h"
|
||||
#include "util.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
#include "protobuf.h"
|
||||
#include "protobuf/cpuinfo.pb-c.h"
|
||||
|
||||
#undef LOG_PREFIX
|
||||
#define LOG_PREFIX "cpu: "
|
||||
|
||||
@@ -220,3 +224,134 @@ int cpu_init(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_dump_cpuinfo(void)
|
||||
{
|
||||
CpuinfoEntry cpu_info = CPUINFO_ENTRY__INIT;
|
||||
CpuinfoX86Entry cpu_x86_info = CPUINFO_X86_ENTRY__INIT;
|
||||
CpuinfoX86Entry *cpu_x86_info_ptr = &cpu_x86_info;
|
||||
struct cr_img *img;
|
||||
|
||||
img = open_image(CR_FD_CPUINFO, O_DUMP);
|
||||
if (!img)
|
||||
return -1;
|
||||
|
||||
cpu_info.x86_entry = &cpu_x86_info_ptr;
|
||||
cpu_info.n_x86_entry = 1;
|
||||
|
||||
cpu_x86_info.vendor_id = (rt_cpu_info.x86_vendor == X86_VENDOR_INTEL) ?
|
||||
CPUINFO_X86_ENTRY__VENDOR__INTEL :
|
||||
CPUINFO_X86_ENTRY__VENDOR__AMD;
|
||||
cpu_x86_info.cpu_family = rt_cpu_info.x86_family;
|
||||
cpu_x86_info.model = rt_cpu_info.x86_model;
|
||||
cpu_x86_info.stepping = rt_cpu_info.x86_mask;
|
||||
cpu_x86_info.capability_ver = 1;
|
||||
cpu_x86_info.n_capability = ARRAY_SIZE(rt_cpu_info.x86_capability);
|
||||
cpu_x86_info.capability = (void *)rt_cpu_info.x86_capability;
|
||||
|
||||
if (rt_cpu_info.x86_model_id[0])
|
||||
cpu_x86_info.model_id = rt_cpu_info.x86_model_id;
|
||||
|
||||
if (pb_write_one(img, &cpu_info, PB_CPUINFO) < 0) {
|
||||
close_image(img);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close_image(img);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpu_validate_features(CpuinfoX86Entry *img_x86_entry)
|
||||
{
|
||||
if (img_x86_entry->n_capability != ARRAY_SIZE(rt_cpu_info.x86_capability)) {
|
||||
/*
|
||||
* Image carries different number of bits.
|
||||
* Simply reject, we can't guarantee anything
|
||||
* in such case.
|
||||
*/
|
||||
pr_err("Size of features in image mismatch "
|
||||
"one provided by run time CPU (%d:%d)\n",
|
||||
(unsigned)img_x86_entry->n_capability,
|
||||
(unsigned)ARRAY_SIZE(rt_cpu_info.x86_capability));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((opts.cpu_cap & ~CPU_CAP_FPU) == CPU_CAP_FPU) {
|
||||
/*
|
||||
* If we're requested to check FPU only ignore
|
||||
* any other bit. It's up to a user if the
|
||||
* rest of mismatches won't cause problems.
|
||||
*/
|
||||
|
||||
#define __mismatch_fpu_bit(__bit) \
|
||||
(test_bit(__bit, (void *)img_x86_entry->capability) && \
|
||||
!cpu_has_feature(__bit))
|
||||
if (__mismatch_fpu_bit(X86_FEATURE_FPU) ||
|
||||
__mismatch_fpu_bit(X86_FEATURE_FXSR) ||
|
||||
__mismatch_fpu_bit(X86_FEATURE_XSAVE)) {
|
||||
pr_err("FPU feature required by image "
|
||||
"is not supported on host.\n");
|
||||
return -1;
|
||||
} else
|
||||
return 0;
|
||||
#undef __mismatch_fpu_bit
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME We need to bring ability to run images with lower
|
||||
* features on more capable CPU.
|
||||
*/
|
||||
|
||||
if (memcmp(img_x86_entry->capability, rt_cpu_info.x86_capability,
|
||||
sizeof(rt_cpu_info.x86_capability))) {
|
||||
pr_err("CPU capabilites do not match run time\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_validate_cpuinfo(void)
|
||||
{
|
||||
CpuinfoX86Entry *img_x86_entry;
|
||||
CpuinfoEntry *img_cpu_info;
|
||||
struct cr_img *img;
|
||||
int ret = -1;
|
||||
|
||||
img = open_image(CR_FD_CPUINFO, O_RSTR | O_OPT);
|
||||
if (!img) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pb_read_one(img, &img_cpu_info, PB_CPUINFO) < 0)
|
||||
goto err;
|
||||
|
||||
if (img_cpu_info->n_x86_entry != 1) {
|
||||
pr_err("No x86 related cpuinfo in image, "
|
||||
"corruption (n_x86_entry = %zi)\n",
|
||||
img_cpu_info->n_x86_entry);
|
||||
goto err;
|
||||
}
|
||||
|
||||
img_x86_entry = img_cpu_info->x86_entry[0];
|
||||
if (img_x86_entry->vendor_id != CPUINFO_X86_ENTRY__VENDOR__INTEL &&
|
||||
img_x86_entry->vendor_id != CPUINFO_X86_ENTRY__VENDOR__AMD) {
|
||||
pr_err("Unknown cpu vendor %d\n", img_x86_entry->vendor_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (img_x86_entry->n_capability != ARRAY_SIZE(rt_cpu_info.x86_capability)) {
|
||||
pr_err("Image carries %u words while %u expected\n",
|
||||
(unsigned)img_x86_entry->n_capability,
|
||||
(unsigned)ARRAY_SIZE(rt_cpu_info.x86_capability));
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = cpu_validate_features(img_x86_entry);
|
||||
err:
|
||||
close_image(img);
|
||||
return ret;
|
||||
}
|
||||
|
@@ -199,5 +199,7 @@ struct cpuinfo_x86 {
|
||||
|
||||
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);
|
||||
|
||||
#endif /* __CR_CPU_H__ */
|
||||
|
@@ -1807,6 +1807,11 @@ int cr_dump_tasks(pid_t pid)
|
||||
if (write_img_inventory())
|
||||
goto err;
|
||||
|
||||
if (opts.cpu_cap & CPU_CAP_CPU) {
|
||||
if (cpu_dump_cpuinfo())
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (connect_to_page_server())
|
||||
goto err;
|
||||
|
||||
|
@@ -1863,6 +1863,11 @@ int cr_restore_tasks(void)
|
||||
if (vdso_init())
|
||||
goto err;
|
||||
|
||||
if (opts.cpu_cap & CPU_CAP_CPU) {
|
||||
if (cpu_validate_cpuinfo())
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (prepare_task_entries() < 0)
|
||||
goto err;
|
||||
|
||||
|
@@ -53,7 +53,7 @@ void init_opts(void)
|
||||
INIT_LIST_HEAD(&opts.ext_mounts);
|
||||
INIT_LIST_HEAD(&opts.new_cgroup_roots);
|
||||
|
||||
opts.cpu_cap = CPU_CAP_ALL;
|
||||
opts.cpu_cap = CPU_CAP_DEFAULT;
|
||||
opts.manage_cgroups = false;
|
||||
opts.ps_socket = -1;
|
||||
}
|
||||
|
@@ -5,5 +5,7 @@
|
||||
|
||||
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);
|
||||
|
||||
#endif /* __CR_CPU_H__ */
|
||||
|
Reference in New Issue
Block a user