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, ...@@ -77,14 +77,16 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
return err; 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) int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
{ {
struct iovec iov; struct iovec iov;
user_fpregs_struct_t fpsimd; user_fpregs_struct_t fpsimd;
int i, ret; int ret;
pr_info("Dumping GP/FPU registers for %d\n", pid); 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) ...@@ -102,6 +104,15 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
goto err; 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 // Save the Aarch64 CPU state
for (i = 0; i < 31; ++i) for (i = 0; i < 31; ++i)
...@@ -114,16 +125,13 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core) ...@@ -114,16 +125,13 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
// Save the FP/SIMD state // Save the FP/SIMD state
for (i = 0; i < 32; ++i) for (i = 0; i < 32; ++i)
{ {
core->ti_aarch64->fpsimd->vregs[2*i] = fpsimd.vregs[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 + 1] = fpsimd->vregs[i] >> 64;
} }
assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpsr); assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpsr);
assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpcr); assign_reg(core->ti_aarch64->fpsimd, fpsimd, fpcr);
ret = 0; return 0;
err:
return ret;
} }
int arch_alloc_thread_info(CoreEntry *core) int arch_alloc_thread_info(CoreEntry *core)
...@@ -190,8 +198,8 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core) ...@@ -190,8 +198,8 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
for (i = 0; i < 32; ++i) for (i = 0; i < 32; ++i)
fpsimd->vregs[i] = (__uint128_t)core->ti_aarch64->fpsimd->vregs[2*i] | fpsimd->vregs[i] = (__uint128_t)core->ti_aarch64->fpsimd->vregs[2*i] |
((__uint128_t)core->ti_aarch64->fpsimd->vregs[2*i + 1] << 64); ((__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, fpsr);
assign_reg(fpsimd, *core->ti_aarch64->fpsimd, fpcr); assign_reg(fpsimd, core->ti_aarch64->fpsimd, fpcr);
fpsimd->head.magic = FPSIMD_MAGIC; fpsimd->head.magic = FPSIMD_MAGIC;
fpsimd->head.size = sizeof(*fpsimd); fpsimd->head.size = sizeof(*fpsimd);
......
...@@ -79,7 +79,10 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, ...@@ -79,7 +79,10 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
return err; 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 #define PTRACE_GETVFPREGS 27
int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core) 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) ...@@ -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 // Save the ARM CPU state
assign_reg(core->ti_arm->gpregs, regs, r0); 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) ...@@ -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, lr);
assign_reg(core->ti_arm->gpregs, regs, pc); assign_reg(core->ti_arm->gpregs, regs, pc);
assign_reg(core->ti_arm->gpregs, regs, cpsr); 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 // Save the VFP state
memcpy(CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs, &vfp.fpregs, sizeof(vfp.fpregs)); memcpy(CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs, &fpregs->fpregs, sizeof(fpregs->fpregs));
CORE_THREAD_ARCH_INFO(core)->fpstate->fpscr = vfp.fpscr; CORE_THREAD_ARCH_INFO(core)->fpstate->fpscr = fpregs->fpscr;
ret = 0; return 0;
err:
return ret;
} }
int arch_alloc_thread_info(CoreEntry *core) int arch_alloc_thread_info(CoreEntry *core)
......
...@@ -112,9 +112,12 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, ...@@ -112,9 +112,12 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
return err; 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) 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; struct iovec iov;
int ret = -1; int ret = -1;
...@@ -138,37 +141,6 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core) ...@@ -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 #ifndef PTRACE_GETREGSET
# define PTRACE_GETREGSET 0x4204 # define PTRACE_GETREGSET 0x4204
#endif #endif
...@@ -196,37 +168,79 @@ int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core) ...@@ -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); xs = &xsave;
assign_reg(core->thread_info->fpregs, xsave.i387, swd); out:
assign_reg(core->thread_info->fpregs, xsave.i387, twd); ret = save_task_regs(core, &regs, xs);
assign_reg(core->thread_info->fpregs, xsave.i387, fop); err:
assign_reg(core->thread_info->fpregs, xsave.i387, rip); return ret;
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); 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 */ /* 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_st_space != ARRAY_SIZE(fpregs->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_xmm_space != ARRAY_SIZE(fpregs->i387.xmm_space));
assign_array(core->thread_info->fpregs, xsave.i387, st_space); assign_array(core->thread_info->fpregs, &fpregs->i387, st_space);
assign_array(core->thread_info->fpregs, xsave.i387, xmm_space); assign_array(core->thread_info->fpregs, &fpregs->i387, xmm_space);
if (cpu_has_feature(X86_FEATURE_XSAVE)) { 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_reg(core->thread_info->fpregs->xsave, &fpregs->xsave_hdr, xstate_bv);
assign_array(core->thread_info->fpregs->xsave, xsave.ymmh, ymmh_space); assign_array(core->thread_info->fpregs->xsave, &fpregs->ymmh, ymmh_space);
} }
#undef assign_reg #undef assign_reg
#undef assign_array #undef assign_array
out: return 0;
ret = 0;
err:
return ret;
} }
int arch_alloc_thread_info(CoreEntry *core) 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