Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Safonov <dima@arista.com>2021-02-26 04:08:00 +0300
committerAndrei Vagin <avagin@gmail.com>2021-09-03 20:31:00 +0300
commit3613b6f15fa8357e8f38f9377c51806e90b452d3 (patch)
tree5eeae937106d8eee5f7be0d415139d72f59307c3 /compel/arch
parent7af06af10d281b70b3722eab503d5258772de1e8 (diff)
compel: Store extended registers set in the thread context
Extended registers set for task is restored with rt_sigreturn() through prepared sigframe. For threads it's currently lost. Preserve it inside thread context to restore on thread curing. Signed-off-by: Dmitry Safonov <dima@arista.com>
Diffstat (limited to 'compel/arch')
-rw-r--r--compel/arch/aarch64/src/lib/infect.c11
-rw-r--r--compel/arch/arm/src/lib/infect.c9
-rwxr-xr-xcompel/arch/mips/src/lib/infect.c8
-rw-r--r--compel/arch/ppc64/src/lib/infect.c9
-rw-r--r--compel/arch/s390/src/lib/infect.c25
-rw-r--r--compel/arch/x86/src/lib/infect.c14
6 files changed, 40 insertions, 36 deletions
diff --git a/compel/arch/aarch64/src/lib/infect.c b/compel/arch/aarch64/src/lib/infect.c
index 4b5939022..39428cd8d 100644
--- a/compel/arch/aarch64/src/lib/infect.c
+++ b/compel/arch/aarch64/src/lib/infect.c
@@ -60,11 +60,12 @@ int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe,
return 0;
}
-int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
+int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
+ user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
{
+ user_fpregs_struct_t tmp, *fpsimd = ext_regs ? ext_regs : &tmp;
struct iovec iov;
- user_fpregs_struct_t fpsimd;
int ret;
pr_info("Dumping GP/FPU registers for %d\n", pid);
@@ -76,14 +77,14 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
goto err;
}
- iov.iov_base = &fpsimd;
- iov.iov_len = sizeof(fpsimd);
+ iov.iov_base = fpsimd;
+ iov.iov_len = sizeof(*fpsimd);
if ((ret = ptrace(PTRACE_GETREGSET, pid, NT_PRFPREG, &iov))) {
pr_perror("Failed to obtain FPU registers for %d", pid);
goto err;
}
- ret = save(arg, regs, &fpsimd);
+ ret = save(arg, regs, fpsimd);
err:
return ret;
}
diff --git a/compel/arch/arm/src/lib/infect.c b/compel/arch/arm/src/lib/infect.c
index 75b985b74..dd5aa9784 100644
--- a/compel/arch/arm/src/lib/infect.c
+++ b/compel/arch/arm/src/lib/infect.c
@@ -69,15 +69,16 @@ int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe,
}
#define PTRACE_GETVFPREGS 27
-int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
+int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
+ user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
{
- user_fpregs_struct_t vfp;
+ user_fpregs_struct_t tmp, *vfp = ext_regs ? ext_regs : &tmp;
int ret = -1;
pr_info("Dumping GP/FPU registers for %d\n", pid);
- if (ptrace(PTRACE_GETVFPREGS, pid, NULL, &vfp)) {
+ if (ptrace(PTRACE_GETVFPREGS, pid, NULL, vfp)) {
pr_perror("Can't obtain FPU registers for %d", pid);
goto err;
}
@@ -99,7 +100,7 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
}
}
- ret = save(arg, regs, &vfp);
+ ret = save(arg, regs, vfp);
err:
return ret;
}
diff --git a/compel/arch/mips/src/lib/infect.c b/compel/arch/mips/src/lib/infect.c
index 35e947cc0..6a53b3c3b 100755
--- a/compel/arch/mips/src/lib/infect.c
+++ b/compel/arch/mips/src/lib/infect.c
@@ -122,13 +122,14 @@ int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe,
return 0;
}
-int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
+int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
+ user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
{
- user_fpregs_struct_t xsave = { }, *xs = NULL;
+ user_fpregs_struct_t xsave = { }, *xs = ext_regs ? ext_regs : &xsave;
int ret = -1;
- if (ptrace(PTRACE_GETFPREGS, pid, NULL, &xsave)) {
+ if (ptrace(PTRACE_GETFPREGS, pid, NULL, xs)) {
pr_perror("Can't obtain FPU registers for %d", pid);
return ret;
}
@@ -151,7 +152,6 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
regs->regs[0] = 0;
}
- xs = &xsave;
ret = save(arg, regs, xs);
return ret;
}
diff --git a/compel/arch/ppc64/src/lib/infect.c b/compel/arch/ppc64/src/lib/infect.c
index b2c725f62..339e01209 100644
--- a/compel/arch/ppc64/src/lib/infect.c
+++ b/compel/arch/ppc64/src/lib/infect.c
@@ -372,17 +372,18 @@ static int __get_task_regs(pid_t pid, user_regs_struct_t *regs,
return 0;
}
-int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
+int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
+ user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
{
- user_fpregs_struct_t fpregs;
+ user_fpregs_struct_t tmp, *fpregs = ext_regs ? ext_regs : &tmp;
int ret;
- ret = __get_task_regs(pid, regs, &fpregs);
+ ret = __get_task_regs(pid, regs, fpregs);
if (ret)
return ret;
- return save(arg, regs, &fpregs);
+ return save(arg, regs, fpregs);
}
int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
diff --git a/compel/arch/s390/src/lib/infect.c b/compel/arch/s390/src/lib/infect.c
index 5a4675449..5b3c0d62e 100644
--- a/compel/arch/s390/src/lib/infect.c
+++ b/compel/arch/s390/src/lib/infect.c
@@ -310,31 +310,32 @@ static int s390_disable_ri_bit(pid_t pid, user_regs_struct_t *regs)
/*
* Prepare task registers for restart
*/
-int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
+int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
+ user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, __maybe_unused unsigned long flags)
{
- user_fpregs_struct_t fpregs;
+ user_fpregs_struct_t tmp, *fpregs = ext_regs ? ext_regs : &tmp;
struct iovec iov;
int rewind;
- print_user_regs_struct("get_task_regs", pid, regs);
+ print_user_regs_struct("compel_get_task_regs", pid, regs);
- memset(&fpregs, 0, sizeof(fpregs));
- iov.iov_base = &fpregs.prfpreg;
- iov.iov_len = sizeof(fpregs.prfpreg);
+ memset(fpregs, 0, sizeof(*fpregs));
+ iov.iov_base = &fpregs->prfpreg;
+ iov.iov_len = sizeof(fpregs->prfpreg);
if (ptrace(PTRACE_GETREGSET, pid, NT_PRFPREG, &iov) < 0) {
pr_perror("Couldn't get floating-point registers");
return -1;
}
- if (get_vx_regs(pid, &fpregs)) {
+ if (get_vx_regs(pid, fpregs)) {
pr_perror("Couldn't get vector registers");
return -1;
}
- if (get_gs_cb(pid, &fpregs)) {
+ if (get_gs_cb(pid, fpregs)) {
pr_perror("Couldn't get guarded-storage");
return -1;
}
- if (get_ri_cb(pid, &fpregs)) {
+ if (get_ri_cb(pid, fpregs)) {
pr_perror("Couldn't get runtime-instrumentation");
return -1;
}
@@ -343,10 +344,10 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
* before we execute parasite code. Otherwise parasite operations
* would be recorded.
*/
- if (fpregs.flags & USER_RI_ON)
+ if (fpregs->flags & USER_RI_ON)
s390_disable_ri_bit(pid, regs);
- print_user_fpregs_struct("get_task_regs", pid, &fpregs);
+ print_user_fpregs_struct("compel_get_task_regs", pid, fpregs);
/* Check for system call restarting. */
if (regs->system_call) {
rewind = regs->system_call >> 16;
@@ -366,7 +367,7 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
}
}
/* Call save_task_regs() */
- return save(arg, regs, &fpregs);
+ return save(arg, regs, fpregs);
}
/*
diff --git a/compel/arch/x86/src/lib/infect.c b/compel/arch/x86/src/lib/infect.c
index 401001942..9d81083f7 100644
--- a/compel/arch/x86/src/lib/infect.c
+++ b/compel/arch/x86/src/lib/infect.c
@@ -334,10 +334,11 @@ static int corrupt_extregs(pid_t pid)
return 0;
}
-int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
+int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs,
+ user_fpregs_struct_t *ext_regs, save_regs_t save,
void *arg, unsigned long flags)
{
- user_fpregs_struct_t xsave = { }, *xs = NULL;
+ user_fpregs_struct_t xsave = { }, *xs = ext_regs ? ext_regs : &xsave;
int ret = -1;
pr_info("Dumping general registers for %d in %s mode\n", pid,
@@ -371,18 +372,18 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
pr_info("Dumping GP/FPU registers for %d\n", pid);
if (!compel_cpu_has_feature(X86_FEATURE_OSXSAVE)) {
- ret = get_task_fpregs(pid, &xsave);
+ ret = get_task_fpregs(pid, xs);
} else if (unlikely(flags & INFECT_X86_PTRACE_MXCSR_BUG)) {
/*
* get_task_fpregs() will fill FP state,
* get_task_xsave() will overwrite rightly sse/mmx/etc
*/
pr_warn("Skylake xsave fpu bug workaround used\n");
- ret = get_task_fpregs(pid, &xsave);
+ ret = get_task_fpregs(pid, xs);
if (!ret)
- ret = get_task_xsave(pid, &xsave);
+ ret = get_task_xsave(pid, xs);
} else {
- ret = get_task_xsave(pid, &xsave);
+ ret = get_task_xsave(pid, xs);
}
if (!ret && unlikely(flags & INFECT_CORRUPT_EXTREGS))
@@ -391,7 +392,6 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
if (ret)
goto err;
- xs = &xsave;
out:
ret = save(arg, regs, xs);
err: