Commit 5978380b authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

restore: use a concrete object for constructing sigframe

struct thread_restore_args contains many pointers on different objects,
only a few of them are really required.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 3ac0ad83
......@@ -206,11 +206,11 @@ void arch_free_thread_info(CoreEntry *core)
}
}
int sigreturn_prep_fpu_frame(struct thread_restore_args *args, CoreEntry *core)
int sigreturn_prep_fpu_frame(fpu_state_t *fpu_state, CoreEntry *core)
{
memcpy(args->fpu_state.ufp.fpregs, CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs,
sizeof(args->fpu_state.ufp.fpregs));
args->fpu_state.ufp.fpscr = CORE_THREAD_ARCH_INFO(core)->fpstate->fpscr;
memcpy(fpu_state->ufp.fpregs, CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs,
sizeof(fpu_state->ufp.fpregs));
fpu_state->ufp.fpscr = CORE_THREAD_ARCH_INFO(core)->fpstate->fpscr;
return 0;
}
......
......@@ -20,6 +20,6 @@ static inline void core_get_tls(CoreEntry *pcore, u32 *ptls)
}
int sigreturn_prep_fpu_frame(struct thread_restore_args *args, CoreEntry *core);
int sigreturn_prep_fpu_frame(fpu_state_t *fpu_state, CoreEntry *core);
#endif
......@@ -62,6 +62,8 @@ struct sigframe {
struct rt_sigframe {
struct rt_siginfo info;
struct sigframe sig;
fpu_state_t fpu_state;
};
......@@ -128,7 +130,7 @@ struct rt_sigframe {
int restore_gpregs(struct rt_sigframe *f, UserArmRegsEntry *r);
int restore_fpu(struct rt_sigframe *sigframe, struct thread_restore_args *args);
int restore_fpu(struct rt_sigframe *sigframe, fpu_state_t *fpu_state);
static inline void restore_tls(u32 tls) {
asm (
......
......@@ -230,6 +230,8 @@ static inline uint64_t encode_pointer(void *p) { return (uint32_t)p; }
typedef struct {
struct user_vfp ufp;
struct user_vfp_exc ufp_exc;
bool has_fpu;
} fpu_state_t;
#endif /* __CR_ASM_TYPES_H__ */
......@@ -38,13 +38,13 @@ int restore_gpregs(struct rt_sigframe *f, UserArmRegsEntry *r)
return 0;
}
int restore_fpu(struct rt_sigframe *sigframe, struct thread_restore_args *args)
int restore_fpu(struct rt_sigframe *sigframe, fpu_state_t *fpu_state)
{
struct aux_sigframe *aux = (struct aux_sigframe *)&sigframe->sig.uc.uc_regspace;
aux->vfp.magic = VFP_MAGIC;
aux->vfp.size = VFP_STORAGE_SIZE;
builtin_memcpy(&aux->vfp.ufp, &args->fpu_state.ufp, sizeof(aux->vfp.ufp));
builtin_memcpy(&aux->vfp.ufp, &fpu_state->ufp, sizeof(aux->vfp.ufp));
return 0;
}
......@@ -379,9 +379,9 @@ static void show_rt_xsave_frame(struct xsave_struct *x)
pr_debug("-----------------------\n");
}
int sigreturn_prep_fpu_frame(struct thread_restore_args *args, CoreEntry *core)
int sigreturn_prep_fpu_frame(fpu_state_t *fpu_state, CoreEntry *core)
{
struct xsave_struct *x = &args->fpu_state.xsave;
struct xsave_struct *x = &fpu_state->xsave;
/*
* If no FPU information provided -- we're restoring
......@@ -389,14 +389,14 @@ int sigreturn_prep_fpu_frame(struct thread_restore_args *args, CoreEntry *core)
* has no FPU support at all.
*/
if (!core->thread_info->fpregs) {
args->has_fpu = false;
fpu_state->has_fpu = false;
return 0;
}
if (!valid_xsave_frame(core))
return -1;
args->has_fpu = true;
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))
......@@ -428,7 +428,7 @@ int sigreturn_prep_fpu_frame(struct thread_restore_args *args, CoreEntry *core)
/*
* This should be at the end of xsave frame.
*/
magic2 = args->fpu_state.__pad + sizeof(struct xsave_struct);
magic2 = fpu_state->__pad + sizeof(struct xsave_struct);
*(u32 *)magic2 = FP_XSTATE_MAGIC2;
}
......
......@@ -94,6 +94,8 @@ typedef struct {
struct xsave_struct xsave;
unsigned char __pad[sizeof(struct xsave_struct) + FP_XSTATE_MAGIC2_SIZE];
};
bool has_fpu;
} fpu_state_t;
#endif /* __CR_ASM_FPU_H__ */
......@@ -18,6 +18,6 @@
#define core_get_tls(pcore, ptls)
int sigreturn_prep_fpu_frame(struct thread_restore_args *args, CoreEntry *core);
int sigreturn_prep_fpu_frame(fpu_state_t *fpu_state, CoreEntry *core);
#endif
......@@ -68,7 +68,7 @@ struct rt_sigframe {
struct rt_ucontext uc;
struct rt_siginfo info;
/* fp state follows here */
fpu_state_t fpu_state;
};
......@@ -136,7 +136,7 @@ struct rt_sigframe {
int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r);
int restore_fpu(struct rt_sigframe *sigframe, struct thread_restore_args *args);
int restore_fpu(struct rt_sigframe *sigframe, fpu_state_t *fpu_state);
static inline void restore_tls(u32 tls) { }
......
......@@ -55,17 +55,18 @@ int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r)
return 0;
}
int restore_fpu(struct rt_sigframe *sigframe, struct thread_restore_args *args)
int restore_fpu(struct rt_sigframe *sigframe, fpu_state_t *fpu_state)
{
if (args->has_fpu) {
unsigned long addr = (unsigned long)(void *)&args->fpu_state.xsave;
unsigned long addr = (unsigned long)(void *)&fpu_state->xsave;
if ((addr % 64ul) == 0ul) {
sigframe->uc.uc_mcontext.fpstate = &args->fpu_state.xsave;
} else {
pr_err("Unaligned address passed: %lx\n", addr);
return -1;
}
if (!fpu_state->has_fpu)
return 0;
if ((addr % 64ul) == 0ul) {
sigframe->uc.uc_mcontext.fpstate = &fpu_state->xsave;
} else {
pr_err("Unaligned address passed: %lx\n", addr);
return -1;
}
return 0;
......
......@@ -2049,7 +2049,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
goto err;
}
if (sigreturn_prep_fpu_frame(&thread_args[i], tcore))
if (sigreturn_prep_fpu_frame(&thread_args[i].fpu_state, tcore))
goto err;
if (thread_args[i].pid != pid)
......
......@@ -80,7 +80,6 @@ struct thread_restore_args {
struct task_restore_core_args *ta;
bool has_fpu;
fpu_state_t fpu_state;
u32 tls;
......
......@@ -262,7 +262,8 @@ static int restore_thread_common(struct rt_sigframe *sigframe,
RT_SIGFRAME_UC(sigframe).uc_sigmask = args->blk_sigset;
restore_sched_info(&args->sp);
if (restore_fpu(sigframe, args))
if (restore_fpu(sigframe, &args->fpu_state))
return -1;
if (restore_gpregs(sigframe, &args->gpregs))
......
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