Esempio n. 1
0
File: infect.c Progetto: xemul/criu
static int __get_task_regs(pid_t pid, user_regs_struct_t *regs,
			   user_fpregs_struct_t *fpregs)
{
	pr_info("Dumping GP/FPU registers for %d\n", pid);

	/*
	 * This is inspired by kernel function check_syscall_restart in
	 * arch/powerpc/kernel/signal.c
	 */
#ifndef TRAP
#define TRAP(r)              ((r).trap & ~0xF)
#endif

	if (TRAP(*regs) == 0x0C00 && regs->ccr & 0x10000000) {
		/* Restart the system call */
		switch (regs->gpr[3]) {
		case ERESTARTNOHAND:
		case ERESTARTSYS:
		case ERESTARTNOINTR:
			regs->gpr[3] = regs->orig_gpr3;
			regs->nip -= 4;
			break;
		case ERESTART_RESTARTBLOCK:
			regs->gpr[0] = __NR_restart_syscall;
			regs->nip -= 4;
			break;
		}
	}

	/* Resetting trap since we are now coming from user space. */
	regs->trap = 0;

	fpregs->flags = 0;
	/*
	 * Check for Transactional Memory operation in progress.
	 * Until we have support of TM register's state through the ptrace API,
	 * we can't checkpoint process with TM operation in progress (almost
	 * impossible) or suspended (easy to get).
	 */
	if (MSR_TM_ACTIVE(regs->msr)) {
		pr_debug("Task %d has %s TM operation at 0x%lx\n",
			 pid,
			 (regs->msr & MSR_TMS) ? "a suspended" : "an active",
			 regs->nip);
		if (get_tm_regs(pid, fpregs))
			return -1;
		fpregs->flags = USER_FPREGS_FL_TM;
	}

	if (get_fpu_regs(pid, fpregs))
		return -1;

	if (get_altivec_regs(pid, fpregs))
		return -1;

	if (fpregs->flags & USER_FPREGS_FL_ALTIVEC) {
		/*
		 * Save the VSX registers if Altivec registers are supported
		 */
		if (get_vsx_regs(pid, fpregs))
			return -1;
	}
	return 0;
}
Esempio n. 2
0
int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
{
	int i;

	pr_info("Dumping GP/FPU registers for %d\n", pid);

	/*
	 * This is inspired by kernel function check_syscall_restart in
	 * arch/powerpc/kernel/signal.c
	 */
#ifndef TRAP
#define TRAP(r)              ((r).trap & ~0xF)
#endif

	if (TRAP(regs) == 0x0C00 && regs.ccr & 0x10000000) {
		/* Restart the system call */
		switch (regs.gpr[3]) {
		case ERESTARTNOHAND:
		case ERESTARTSYS:
		case ERESTARTNOINTR:
			regs.gpr[3] = regs.orig_gpr3;
			regs.nip -= 4;
			break;
		case ERESTART_RESTARTBLOCK:
			regs.gpr[0] = __NR_restart_syscall;
			regs.nip -= 4;
			break;
		}
	}

	/* Resetting trap since we are now comming from user space. */
	regs.trap = 0;

#define assign_reg(dst, src, e) do {			\
		dst->e = (__typeof__(dst->e))src.e;	\
} while (0)

	for (i=0; i<32; i++)
		assign_reg(core->ti_ppc64->gpregs, regs, gpr[i]);

	assign_reg(core->ti_ppc64->gpregs, regs, nip);
	assign_reg(core->ti_ppc64->gpregs, regs, msr);
	assign_reg(core->ti_ppc64->gpregs, regs, orig_gpr3);
	assign_reg(core->ti_ppc64->gpregs, regs, ctr);
	assign_reg(core->ti_ppc64->gpregs, regs, link);
	assign_reg(core->ti_ppc64->gpregs, regs, xer);
	assign_reg(core->ti_ppc64->gpregs, regs, ccr);
	assign_reg(core->ti_ppc64->gpregs, regs, trap);
#undef assign_reg

	if (get_fpu_regs(pid, core))
		return -1;

	if (get_altivec_regs(pid, core))
		return -1;

	/*
	 * Don't save the VSX registers if Altivec registers are not
	 * supported
	 */
	if (CORE_THREAD_ARCH_INFO(core)->vrstate && get_vsx_regs(pid, core))
		return -1;

	return 0;
}