Commit eba074c0 authored by Pavel Emelyanov's avatar Pavel Emelyanov

arch: Split get_task_regs() into get_ and save_ parts

Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent b84d2b78
......@@ -77,14 +77,16 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
return err;
}
static int save_task_regs(CoreEntry *core,
user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd);
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))(src).e
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))(src)->e
int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
{
struct iovec iov;
user_fpregs_struct_t fpsimd;
int i, ret;
int ret;
pr_info("Dumping GP/FPU registers for %d\n", pid);
......@@ -102,6 +104,15 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
goto err;
}
ret = save_task_regs(core, &regs, &fpsimd);
err:
return ret;
}
static int save_task_regs(CoreEntry *core,
user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd)
{
int i;
// Save the Aarch64 CPU state
for (i = 0; i < 31; ++i)
......@@ -114,16 +125,13 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
// 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;
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;
return 0;
}
int arch_alloc_thread_info(CoreEntry *core)
......@@ -190,8 +198,8 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
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);
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);
......
......@@ -79,7 +79,10 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
return err;
}
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))src.ARM_##e
static int save_task_regs(CoreEntry *core,
user_regs_struct_t *regs, user_fpregs_struct_t *fpregs);
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))((src)->ARM_##e)
#define PTRACE_GETVFPREGS 27
int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
......@@ -111,7 +114,14 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
}
}
ret = save_task_regs(core, &regs, &vfp);
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);
......@@ -131,18 +141,15 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
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;
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;
memcpy(CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs, &fpregs->fpregs, sizeof(fpregs->fpregs));
CORE_THREAD_ARCH_INFO(core)->fpstate->fpscr = fpregs->fpscr;
ret = 0;
err:
return ret;
return 0;
}
int arch_alloc_thread_info(CoreEntry *core)
......
......@@ -112,9 +112,12 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
return err;
}
static int save_task_regs(CoreEntry *core,
user_regs_struct_t *regs, user_fpregs_struct_t *fpregs);
int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
{
user_fpregs_struct_t xsave = { };
user_fpregs_struct_t xsave = { }, *xs = NULL;
struct iovec iov;
int ret = -1;
......@@ -138,37 +141,6 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
}
}
#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
......@@ -196,37 +168,79 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
}
}
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);
xs = &xsave;
out:
ret = save_task_regs(core, &regs, xs);
err:
return ret;
}
static int save_task_regs(CoreEntry *core,
user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
{
UserX86RegsEntry *gpregs = core->thread_info->gpregs;
#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(gpregs, regs, r15);
assign_reg(gpregs, regs, r14);
assign_reg(gpregs, regs, r13);
assign_reg(gpregs, regs, r12);
assign_reg(gpregs, regs, bp);
assign_reg(gpregs, regs, bx);
assign_reg(gpregs, regs, r11);
assign_reg(gpregs, regs, r10);
assign_reg(gpregs, regs, r9);
assign_reg(gpregs, regs, r8);
assign_reg(gpregs, regs, ax);
assign_reg(gpregs, regs, cx);
assign_reg(gpregs, regs, dx);
assign_reg(gpregs, regs, si);
assign_reg(gpregs, regs, di);
assign_reg(gpregs, regs, orig_ax);
assign_reg(gpregs, regs, ip);
assign_reg(gpregs, regs, cs);
assign_reg(gpregs, regs, flags);
assign_reg(gpregs, regs, sp);
assign_reg(gpregs, regs, ss);
assign_reg(gpregs, regs, fs_base);
assign_reg(gpregs, regs, gs_base);
assign_reg(gpregs, regs, ds);
assign_reg(gpregs, regs, es);
assign_reg(gpregs, regs, fs);
assign_reg(gpregs, regs, gs);
if (!fpregs)
return 0;
assign_reg(core->thread_info->fpregs, &fpregs->i387, cwd);
assign_reg(core->thread_info->fpregs, &fpregs->i387, swd);
assign_reg(core->thread_info->fpregs, &fpregs->i387, twd);
assign_reg(core->thread_info->fpregs, &fpregs->i387, fop);
assign_reg(core->thread_info->fpregs, &fpregs->i387, rip);
assign_reg(core->thread_info->fpregs, &fpregs->i387, rdp);
assign_reg(core->thread_info->fpregs, &fpregs->i387, mxcsr);
assign_reg(core->thread_info->fpregs, &fpregs->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));
BUG_ON(core->thread_info->fpregs->n_st_space != ARRAY_SIZE(fpregs->i387.st_space));
BUG_ON(core->thread_info->fpregs->n_xmm_space != ARRAY_SIZE(fpregs->i387.xmm_space));
assign_array(core->thread_info->fpregs, xsave.i387, st_space);
assign_array(core->thread_info->fpregs, xsave.i387, xmm_space);
assign_array(core->thread_info->fpregs, &fpregs->i387, st_space);
assign_array(core->thread_info->fpregs, &fpregs->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));
BUG_ON(core->thread_info->fpregs->xsave->n_ymmh_space != ARRAY_SIZE(fpregs->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);
assign_reg(core->thread_info->fpregs->xsave, &fpregs->xsave_hdr, xstate_bv);
assign_array(core->thread_info->fpregs->xsave, &fpregs->ymmh, ymmh_space);
}
#undef assign_reg
#undef assign_array
out:
ret = 0;
err:
return ret;
return 0;
}
int arch_alloc_thread_info(CoreEntry *core)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment