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; }
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; }