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:
authorCyrill Gorcunov <gorcunov@openvz.org>2016-10-31 15:06:48 +0300
committerAndrei Vagin <avagin@virtuozzo.com>2017-03-15 00:06:06 +0300
commitcbe24fb9c438f147fdd70c41f2a66844457ffed4 (patch)
tree375b747a15aa530d377e4be25ecfb42374d8dd61 /compel/arch/aarch64
parent51092282de6daca5cc8927c88b52e58314d40c00 (diff)
compel: Move in parasite engine
This is the final patch in the series. It does a bunch of renames and fixes headers respectively. Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Diffstat (limited to 'compel/arch/aarch64')
-rw-r--r--compel/arch/aarch64/src/lib/include/uapi/asm/breakpoints.h (renamed from compel/arch/aarch64/src/lib/include/ptrace.h)4
-rw-r--r--compel/arch/aarch64/src/lib/include/uapi/asm/infect-types.h57
-rw-r--r--compel/arch/aarch64/src/lib/infect.c111
3 files changed, 170 insertions, 2 deletions
diff --git a/compel/arch/aarch64/src/lib/include/ptrace.h b/compel/arch/aarch64/src/lib/include/uapi/asm/breakpoints.h
index e18454df2..5f090490d 100644
--- a/compel/arch/aarch64/src/lib/include/ptrace.h
+++ b/compel/arch/aarch64/src/lib/include/uapi/asm/breakpoints.h
@@ -1,5 +1,5 @@
-#ifndef __COMPEL_PTRACE_H__
-#define __COMPEL_PTRACE_H__
+#ifndef __COMPEL_BREAKPOINTS_H__
+#define __COMPEL_BREAKPOINTS_H__
#define ARCH_SI_TRAP TRAP_BRKPT
static inline int ptrace_set_breakpoint(pid_t pid, void *addr)
diff --git a/compel/arch/aarch64/src/lib/include/uapi/asm/infect-types.h b/compel/arch/aarch64/src/lib/include/uapi/asm/infect-types.h
new file mode 100644
index 000000000..714881c57
--- /dev/null
+++ b/compel/arch/aarch64/src/lib/include/uapi/asm/infect-types.h
@@ -0,0 +1,57 @@
+#ifndef UAPI_COMPEL_ASM_TYPES_H__
+#define UAPI_COMPEL_ASM_TYPES_H__
+
+#include <stdint.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <asm/ptrace.h>
+#include "common/page.h"
+
+#define SIGMAX 64
+#define SIGMAX_OLD 31
+
+/*
+ * Copied from the Linux kernel header arch/arm64/include/uapi/asm/ptrace.h
+ *
+ * A thread ARM CPU context
+ */
+
+typedef struct user_pt_regs user_regs_struct_t;
+typedef struct user_fpsimd_state user_fpregs_struct_t;
+
+#define REG_RES(r) ((uint64_t)(r).regs[0])
+#define REG_IP(r) ((uint64_t)(r).pc)
+#define REG_SYSCALL_NR(r) ((uint64_t)(r).regs[8])
+
+#define user_regs_native(pregs) true
+
+/*
+ * Range for task size calculated from the following Linux kernel files:
+ * arch/arm64/include/asm/memory.h
+ * arch/arm64/Kconfig
+ *
+ * TODO: handle 32 bit tasks
+ */
+#define TASK_SIZE_MIN (1UL << 39)
+#define TASK_SIZE_MAX (1UL << 48)
+
+static inline unsigned long task_size(void)
+{
+ unsigned long task_size;
+
+ for (task_size = TASK_SIZE_MIN; task_size < TASK_SIZE_MAX; task_size <<= 1)
+ if (munmap((void *)task_size, page_size()))
+ break;
+ return task_size;
+}
+
+#define AT_VECTOR_SIZE 40
+
+typedef uint64_t auxv_t;
+typedef uint64_t tls_t;
+
+#define ARCH_SI_TRAP TRAP_BRKPT
+
+#define __NR(syscall, compat) __NR_##syscall
+
+#endif /* UAPI_COMPEL_ASM_TYPES_H__ */
diff --git a/compel/arch/aarch64/src/lib/infect.c b/compel/arch/aarch64/src/lib/infect.c
new file mode 100644
index 000000000..fceea2816
--- /dev/null
+++ b/compel/arch/aarch64/src/lib/infect.c
@@ -0,0 +1,111 @@
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <linux/elf.h>
+#include <compel/plugins/std/syscall-codes.h>
+#include "uapi/compel/asm/infect-types.h"
+#include "log.h"
+#include "errno.h"
+#include "infect.h"
+#include "infect-priv.h"
+
+/*
+ * Injected syscall instruction
+ */
+const char code_syscall[] = {
+ 0x01, 0x00, 0x00, 0xd4, /* SVC #0 */
+ 0x00, 0x00, 0x20, 0xd4 /* BRK #0 */
+};
+
+static const int
+code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
+
+static inline void __always_unused __check_code_syscall(void)
+{
+ BUILD_BUG_ON(code_syscall_aligned != BUILTIN_SYSCALL_SIZE);
+ BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
+}
+
+int compel_get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t save, void *arg)
+{
+ struct iovec iov;
+ user_fpregs_struct_t fpsimd;
+ int ret;
+
+ pr_info("Dumping GP/FPU registers for %d\n", pid);
+
+ iov.iov_base = &regs;
+ iov.iov_len = sizeof(user_regs_struct_t);
+ if ((ret = ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov))) {
+ pr_perror("Failed to obtain CPU registers for %d", pid);
+ goto err;
+ }
+
+ 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);
+err:
+ return ret;
+}
+
+int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
+ unsigned long arg1,
+ unsigned long arg2,
+ unsigned long arg3,
+ unsigned long arg4,
+ unsigned long arg5,
+ unsigned long arg6)
+{
+ user_regs_struct_t regs = ctl->orig.regs;
+ int err;
+
+ regs.regs[8] = (unsigned long)nr;
+ regs.regs[0] = arg1;
+ regs.regs[1] = arg2;
+ regs.regs[2] = arg3;
+ regs.regs[3] = arg4;
+ regs.regs[4] = arg5;
+ regs.regs[5] = arg6;
+ regs.regs[6] = 0;
+ regs.regs[7] = 0;
+
+ err = compel_execute_syscall(ctl, &regs, code_syscall);
+
+ *ret = regs.regs[0];
+ return err;
+}
+
+void *remote_mmap(struct parasite_ctl *ctl,
+ void *addr, size_t length, int prot,
+ int flags, int fd, off_t offset)
+{
+ unsigned long map;
+ int err;
+
+ err = compel_syscall(ctl, __NR_mmap, &map,
+ (unsigned long)addr, length, prot, flags, fd, offset);
+ if (err < 0 || (long)map < 0)
+ map = 0;
+
+ return (void *)map;
+}
+
+void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
+{
+ regs->pc = new_ip;
+ if (stack)
+ regs->sp = (unsigned long)stack;
+}
+
+bool arch_can_dump_task(struct parasite_ctl *ctl)
+{
+ /*
+ * TODO: Add proper check here
+ */
+ return true;
+}