[CRIU] [PATCH v2 1/5] Restore registers not present in the sigreturn signal frame

Alice Frosi alice at linux.vnet.ibm.com
Thu Oct 5 16:50:39 MSK 2017


Add new function arch_set_task_regs_nosigrt(). It allows to restore
architecture-specific registers not present in sigreturn signal frame.

Each architecture can overwrite this function.

The arch_set_task_regs_nosigrt function restores the registers between the
final sigreturn and PTRACE_DETACH. We do this at this point because
we are sure that all threads have already been created.

Add arch_set_thread_regs in pre-dump because some registers may have
been changed by the parasite infection and they are not present in
sigreturn signal frame.

Signed-off-by: Alice Frosi <alice at linux.vnet.ibm.com>
Reviewed-by: Michael Holzheu <holzheu at linux.vnet.ibm.com>
---
 criu/cr-dump.c         | 16 ++++++++++++++--
 criu/cr-restore.c      | 11 +++++++++++
 criu/include/dump.h    |  3 +++
 criu/include/restore.h |  3 +++
 4 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index c83f5ee9d..a5f38aad3 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -87,8 +87,13 @@
 /*
  * Architectures can overwrite this function to restore register sets that
  * are not covered by ptrace_set/get_regs().
+ *
+ * with_threads = false: Only the register sets of the tasks are restored
+ * with_threads = true : The register sets of the tasks with all their threads
+ *			 are restored
  */
-int __attribute__((weak)) arch_set_thread_regs(struct pstree_item *item)
+int __attribute__((weak)) arch_set_thread_regs(struct pstree_item *item,
+					       bool with_threads)
 {
 	return 0;
 }
@@ -1560,6 +1565,12 @@ static int cr_pre_dump_finish(int ret)
 {
 	struct pstree_item *item;
 
+	/*
+	 * Restore registers for tasks only. The threads have not been
+	 * infected. Therefore, the thread register sets have not been changed.
+	 */
+	if (arch_set_thread_regs(root_item, false) < 0)
+		goto err;
 	pstree_switch_state(root_item, TASK_ALIVE);
 
 	timing_stop(TIME_FROZEN);
@@ -1785,7 +1796,8 @@ static int cr_dump_finish(int ret)
 	if (!ret && opts.lazy_pages)
 		ret = cr_lazy_mem_dump();
 
-	arch_set_thread_regs(root_item);
+	if (arch_set_thread_regs(root_item, true) < 0)
+		return -1;
 	pstree_switch_state(root_item,
 			    (ret || post_dump_ret) ?
 			    TASK_ALIVE : opts.final_state);
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 0ca00a9d9..18a373272 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -122,6 +122,15 @@ static int prepare_rlimits(int pid, struct task_restore_args *, CoreEntry *core)
 static int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core);
 static int prepare_signals(int pid, struct task_restore_args *, CoreEntry *core);
 
+/*
+ * Architectures can overwrite this function to restore registers that are not
+ * present in the sigreturn signal frame.
+ */
+int __attribute__((weak)) arch_set_thread_regs_nosigrt(struct pid *pid)
+{
+	return 0;
+}
+
 static inline int stage_participants(int next_stage)
 {
 	switch (next_stage) {
@@ -2081,6 +2090,8 @@ static void finalize_restore_detach(int status)
 				break;
 			}
 
+			if (arch_set_thread_regs_nosigrt(item->threads[i]))
+				pr_perror("Restoring regs for %d failed", pid);
 			if (ptrace(PTRACE_DETACH, pid, NULL, 0))
 				pr_perror("Unable to execute %d", pid);
 		}
diff --git a/criu/include/dump.h b/criu/include/dump.h
index d9a4b61ad..1c1446886 100644
--- a/criu/include/dump.h
+++ b/criu/include/dump.h
@@ -1,4 +1,7 @@
 #ifndef __CR_INC_DUMP_H__
 #define __CR_INC_DUMP_H__
 #include "asm/dump.h"
+
+extern int arch_set_thread_regs(struct pstree_item *item, bool with_threads);
+
 #endif
diff --git a/criu/include/restore.h b/criu/include/restore.h
index 07e8fd8d7..511f25308 100644
--- a/criu/include/restore.h
+++ b/criu/include/restore.h
@@ -1,8 +1,11 @@
 #ifndef __CR_INC_RESTORE_H__
 #define __CR_INC_RESTORE_H__
+
+#include "pid.h"
 #include "types.h"
 #include "asm/restore.h"
 
 extern int criu_signals_setup(void (*handler)(int, siginfo_t *, void *));
+extern int arch_set_thread_regs_nosigrt(struct pid *pid);
 
 #endif
-- 
2.13.5



More information about the CRIU mailing list