int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core) { int i; struct fpsimd_context *fpsimd = &RT_SIGFRAME_FPU(sigframe); if (core->ti_aarch64->fpsimd->n_vregs != 64) return 1; for (i = 0; i < 32; ++i) fpsimd->vregs[i] = (__uint128_t)core->ti_aarch64->fpsimd->vregs[2*i] | ((__uint128_t)core->ti_aarch64->fpsimd->vregs[2*i + 1] << 64); assign_reg(fpsimd, *core->ti_aarch64->fpsimd, fpsr); assign_reg(fpsimd, *core->ti_aarch64->fpsimd, fpcr); fpsimd->head.magic = FPSIMD_MAGIC; fpsimd->head.size = sizeof(*fpsimd); return 0; }
void fs_visitor::assign_regs_trivial() { unsigned hw_reg_mapping[this->alloc.count + 1]; unsigned i; int reg_width = dispatch_width / 8; /* Note that compressed instructions require alignment to 2 registers. */ hw_reg_mapping[0] = ALIGN(this->first_non_payload_grf, reg_width); for (i = 1; i <= this->alloc.count; i++) { hw_reg_mapping[i] = (hw_reg_mapping[i - 1] + this->alloc.sizes[i - 1]); } this->grf_used = hw_reg_mapping[this->alloc.count]; foreach_block_and_inst(block, fs_inst, inst, cfg) { assign_reg(hw_reg_mapping, &inst->dst); for (i = 0; i < inst->sources; i++) { assign_reg(hw_reg_mapping, &inst->src[i]); } }
static void copy_gp_regs(UserPpc64RegsEntry *dst, user_regs_struct_t *src) { int i; #define assign_reg(e) do { \ dst->e = (__typeof__(dst->e))src->e; \ } while (0) for (i=0; i<32; i++) assign_reg(gpr[i]); assign_reg(nip); assign_reg(msr); assign_reg(orig_gpr3); assign_reg(ctr); assign_reg(link); assign_reg(xer); assign_reg(ccr); assign_reg(trap); #undef assign_reg }
int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core) { struct iovec iov; struct user_fpsimd_state fpsimd; int i, ret; pr_info("Dumping GP/FPU registers for %d\n", pid); iov.iov_base = ®s; iov.iov_len = sizeof(user_regs_struct_t); if ((ret = ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov))) { pr_err("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_err("Failed to obtain FPU registers for %d!", pid); goto err; } // Save the Aarch64 CPU state for (i = 0; i < 31; ++i) assign_reg(core->ti_aarch64->gpregs, regs, regs[i]); assign_reg(core->ti_aarch64->gpregs, regs, sp); assign_reg(core->ti_aarch64->gpregs, regs, pc); assign_reg(core->ti_aarch64->gpregs, regs, pstate); // Save the FP/SIMD state for (i = 0; i < 32; ++i) { core->ti_aarch64->fpsimd->vregs[2*i] = fpsimd.vregs[i]; core->ti_aarch64->fpsimd->vregs[2*i + 1] = fpsimd.vregs[i] >> 64; } assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpsr); assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpcr); ret = 0; err: return ret; }
int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core) { fpu_state_t *fpu_state = &sigframe->fpu_state; struct xsave_struct *x = &fpu_state->xsave; /* * If no FPU information provided -- we're restoring * old image which has no FPU support, or the dump simply * has no FPU support at all. */ if (!core->thread_info->fpregs) { fpu_state->has_fpu = false; return 0; } if (!valid_xsave_frame(core)) return -1; fpu_state->has_fpu = true; #define assign_reg(dst, src, e) do { dst.e = (__typeof__(dst.e))src->e; } while (0) #define assign_array(dst, src, e) memcpy(dst.e, (src)->e, sizeof(dst.e)) assign_reg(x->i387, core->thread_info->fpregs, cwd); assign_reg(x->i387, core->thread_info->fpregs, swd); assign_reg(x->i387, core->thread_info->fpregs, twd); assign_reg(x->i387, core->thread_info->fpregs, fop); assign_reg(x->i387, core->thread_info->fpregs, rip); assign_reg(x->i387, core->thread_info->fpregs, rdp); assign_reg(x->i387, core->thread_info->fpregs, mxcsr); assign_reg(x->i387, core->thread_info->fpregs, mxcsr_mask); assign_array(x->i387, core->thread_info->fpregs, st_space); assign_array(x->i387, core->thread_info->fpregs, xmm_space); if (cpu_has_feature(X86_FEATURE_XSAVE)) { struct fpx_sw_bytes *fpx_sw = (void *)&x->i387.sw_reserved; void *magic2; x->xsave_hdr.xstate_bv = XSTATE_FP | XSTATE_SSE | XSTATE_YMM; /* * fpregs->xsave pointer might not present on image so we * simply clear out all ymm registers. */ if (core->thread_info->fpregs->xsave) assign_array(x->ymmh, core->thread_info->fpregs->xsave, ymmh_space); fpx_sw->magic1 = FP_XSTATE_MAGIC1; fpx_sw->xstate_bv = XSTATE_FP | XSTATE_SSE | XSTATE_YMM; fpx_sw->xstate_size = sizeof(struct xsave_struct); fpx_sw->extended_size = sizeof(struct xsave_struct) + FP_XSTATE_MAGIC2_SIZE; /* * This should be at the end of xsave frame. */ magic2 = fpu_state->__pad + sizeof(struct xsave_struct); *(u32 *)magic2 = FP_XSTATE_MAGIC2; } show_rt_xsave_frame(x); #undef assign_reg #undef assign_array return 0; }
int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core) { struct xsave_struct xsave = { }; struct iovec iov; int ret = -1; pr_info("Dumping GP/FPU registers for %d\n", pid); /* Did we come from a system call? */ if ((int)regs.orig_ax >= 0) { /* Restart the system call */ switch ((long)(int)regs.ax) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs.ax = regs.orig_ax; regs.ip -= 2; break; case -ERESTART_RESTARTBLOCK: pr_warn("Will restore %d with interrupted system call\n", pid); regs.ax = -EINTR; break; } } #define assign_reg(dst, src, e) do { dst->e = (__typeof__(dst->e))src.e; } while (0) #define assign_array(dst, src, e) memcpy(dst->e, &src.e, sizeof(src.e)) assign_reg(core->thread_info->gpregs, regs, r15); assign_reg(core->thread_info->gpregs, regs, r14); assign_reg(core->thread_info->gpregs, regs, r13); assign_reg(core->thread_info->gpregs, regs, r12); assign_reg(core->thread_info->gpregs, regs, bp); assign_reg(core->thread_info->gpregs, regs, bx); assign_reg(core->thread_info->gpregs, regs, r11); assign_reg(core->thread_info->gpregs, regs, r10); assign_reg(core->thread_info->gpregs, regs, r9); assign_reg(core->thread_info->gpregs, regs, r8); assign_reg(core->thread_info->gpregs, regs, ax); assign_reg(core->thread_info->gpregs, regs, cx); assign_reg(core->thread_info->gpregs, regs, dx); assign_reg(core->thread_info->gpregs, regs, si); assign_reg(core->thread_info->gpregs, regs, di); assign_reg(core->thread_info->gpregs, regs, orig_ax); assign_reg(core->thread_info->gpregs, regs, ip); assign_reg(core->thread_info->gpregs, regs, cs); assign_reg(core->thread_info->gpregs, regs, flags); assign_reg(core->thread_info->gpregs, regs, sp); assign_reg(core->thread_info->gpregs, regs, ss); assign_reg(core->thread_info->gpregs, regs, fs_base); assign_reg(core->thread_info->gpregs, regs, gs_base); assign_reg(core->thread_info->gpregs, regs, ds); assign_reg(core->thread_info->gpregs, regs, es); assign_reg(core->thread_info->gpregs, regs, fs); assign_reg(core->thread_info->gpregs, regs, gs); #ifndef PTRACE_GETREGSET # define PTRACE_GETREGSET 0x4204 #endif if (!cpu_has_feature(X86_FEATURE_FPU)) goto out; /* * FPU fetched either via fxsave or via xsave, * thus decode it accrodingly. */ if (cpu_has_feature(X86_FEATURE_XSAVE)) { iov.iov_base = &xsave; iov.iov_len = sizeof(xsave); if (ptrace(PTRACE_GETREGSET, pid, (unsigned int)NT_X86_XSTATE, &iov) < 0) { pr_perror("Can't obtain FPU registers for %d", pid); goto err; } } else { if (ptrace(PTRACE_GETFPREGS, pid, NULL, &xsave)) { pr_perror("Can't obtain FPU registers for %d", pid); goto err; } } assign_reg(core->thread_info->fpregs, xsave.i387, cwd); assign_reg(core->thread_info->fpregs, xsave.i387, swd); assign_reg(core->thread_info->fpregs, xsave.i387, twd); assign_reg(core->thread_info->fpregs, xsave.i387, fop); assign_reg(core->thread_info->fpregs, xsave.i387, rip); assign_reg(core->thread_info->fpregs, xsave.i387, rdp); assign_reg(core->thread_info->fpregs, xsave.i387, mxcsr); assign_reg(core->thread_info->fpregs, xsave.i387, mxcsr_mask); /* Make sure we have enough space */ BUG_ON(core->thread_info->fpregs->n_st_space != ARRAY_SIZE(xsave.i387.st_space)); BUG_ON(core->thread_info->fpregs->n_xmm_space != ARRAY_SIZE(xsave.i387.xmm_space)); assign_array(core->thread_info->fpregs, xsave.i387, st_space); assign_array(core->thread_info->fpregs, xsave.i387, xmm_space); if (cpu_has_feature(X86_FEATURE_XSAVE)) { BUG_ON(core->thread_info->fpregs->xsave->n_ymmh_space != ARRAY_SIZE(xsave.ymmh.ymmh_space)); assign_reg(core->thread_info->fpregs->xsave, xsave.xsave_hdr, xstate_bv); assign_array(core->thread_info->fpregs->xsave, xsave.ymmh, ymmh_space); } #undef assign_reg #undef assign_array out: ret = 0; err: return ret; }
static int save_task_regs(CoreEntry *core, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs) { // Save the ARM CPU state assign_reg(core->ti_arm->gpregs, regs, r0); assign_reg(core->ti_arm->gpregs, regs, r1); assign_reg(core->ti_arm->gpregs, regs, r2); assign_reg(core->ti_arm->gpregs, regs, r3); assign_reg(core->ti_arm->gpregs, regs, r4); assign_reg(core->ti_arm->gpregs, regs, r5); assign_reg(core->ti_arm->gpregs, regs, r6); assign_reg(core->ti_arm->gpregs, regs, r7); assign_reg(core->ti_arm->gpregs, regs, r8); assign_reg(core->ti_arm->gpregs, regs, r9); assign_reg(core->ti_arm->gpregs, regs, r10); assign_reg(core->ti_arm->gpregs, regs, fp); assign_reg(core->ti_arm->gpregs, regs, ip); assign_reg(core->ti_arm->gpregs, regs, sp); assign_reg(core->ti_arm->gpregs, regs, lr); assign_reg(core->ti_arm->gpregs, regs, pc); assign_reg(core->ti_arm->gpregs, regs, cpsr); core->ti_arm->gpregs->orig_r0 = regs->ARM_ORIG_r0; // Save the VFP state memcpy(CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs, &fpregs->fpregs, sizeof(fpregs->fpregs)); CORE_THREAD_ARCH_INFO(core)->fpstate->fpscr = fpregs->fpscr; 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; }
int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core) { struct user_vfp vfp; int ret = -1; pr_info("Dumping GP/FPU registers for %d\n", pid); if (ptrace(PTRACE_GETVFPREGS, pid, NULL, &vfp)) { pr_perror("Can't obtain FPU registers for %d", pid); goto err; } /* Did we come from a system call? */ if ((int)regs.ARM_ORIG_r0 >= 0) { /* Restart the system call */ switch ((long)(int)regs.ARM_r0) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: regs.ARM_r0 = regs.ARM_ORIG_r0; regs.ARM_pc -= 4; break; case -ERESTART_RESTARTBLOCK: regs.ARM_r0 = __NR_restart_syscall; regs.ARM_pc -= 4; break; } } // Save the ARM CPU state assign_reg(core->ti_arm->gpregs, regs, r0); assign_reg(core->ti_arm->gpregs, regs, r1); assign_reg(core->ti_arm->gpregs, regs, r2); assign_reg(core->ti_arm->gpregs, regs, r3); assign_reg(core->ti_arm->gpregs, regs, r4); assign_reg(core->ti_arm->gpregs, regs, r5); assign_reg(core->ti_arm->gpregs, regs, r6); assign_reg(core->ti_arm->gpregs, regs, r7); assign_reg(core->ti_arm->gpregs, regs, r8); assign_reg(core->ti_arm->gpregs, regs, r9); assign_reg(core->ti_arm->gpregs, regs, r10); assign_reg(core->ti_arm->gpregs, regs, fp); assign_reg(core->ti_arm->gpregs, regs, ip); assign_reg(core->ti_arm->gpregs, regs, sp); assign_reg(core->ti_arm->gpregs, regs, lr); assign_reg(core->ti_arm->gpregs, regs, pc); assign_reg(core->ti_arm->gpregs, regs, cpsr); core->ti_arm->gpregs->orig_r0 = regs.ARM_ORIG_r0; // Save the VFP state memcpy(CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs, &vfp.fpregs, sizeof(vfp.fpregs)); CORE_THREAD_ARCH_INFO(core)->fpstate->fpscr = vfp.fpscr; ret = 0; err: return ret; }