Commit 1982fddb authored by Alexander Kartashov's avatar Alexander Kartashov Committed by Pavel Emelyanov

cr: generalized the prototype of the routine restore_fpu()

A struct sigframe* instead of fpu_state_t should be passed
to the routine restore_fpu() since FPU registers are stored
in different fields of the sigframe in different architectures.
An architecture-specific implementation of the routine restore_fpu()
should know details of this layout instead of construct_sigframe().

This change makes it possible to move ARM FPU restoration
from sigreturn_prep_fpu_frame() (where it caused a segfault
since the pointer fpu_stat has become invalid in the dumper
address space) to restore_fpu()
Signed-off-by: 's avatarAlexander Kartashov <alekskartashov@parallels.com>
Acked-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent de71bc69
...@@ -197,10 +197,12 @@ void arch_free_thread_info(CoreEntry *core) ...@@ -197,10 +197,12 @@ void arch_free_thread_info(CoreEntry *core)
} }
} }
int restore_fpu(fpu_state_t *fpu_state, CoreEntry *core) int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
{ {
memcpy(fpu_state->ufp.fpregs, CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs, struct aux_sigframe *aux = (struct aux_sigframe *)&sigframe->sig.uc.uc_regspace;
sizeof(fpu_state->ufp.fpregs)); fpu_state_t *fpu_state = &sigframe->fpu_state;
memcpy(&aux->vfp.ufp, CORE_THREAD_ARCH_INFO(core)->fpstate->vfp_regs, sizeof(aux->vfp.ufp));
fpu_state->ufp.fpscr = CORE_THREAD_ARCH_INFO(core)->fpstate->fpscr; fpu_state->ufp.fpscr = CORE_THREAD_ARCH_INFO(core)->fpstate->fpscr;
return 0; return 0;
...@@ -259,7 +261,6 @@ int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, fpu_state_t *fpu_stat ...@@ -259,7 +261,6 @@ int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, fpu_state_t *fpu_stat
aux->vfp.magic = VFP_MAGIC; aux->vfp.magic = VFP_MAGIC;
aux->vfp.size = VFP_STORAGE_SIZE; aux->vfp.size = VFP_STORAGE_SIZE;
builtin_memcpy(&aux->vfp.ufp, &fpu_state->ufp, sizeof(aux->vfp.ufp));
return 0; return 0;
} }
...@@ -20,6 +20,6 @@ static inline void core_get_tls(CoreEntry *pcore, u32 *ptls) ...@@ -20,6 +20,6 @@ static inline void core_get_tls(CoreEntry *pcore, u32 *ptls)
} }
int restore_fpu(fpu_state_t *fpu_state, CoreEntry *core); int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core);
#endif #endif
...@@ -373,8 +373,9 @@ static void show_rt_xsave_frame(struct xsave_struct *x) ...@@ -373,8 +373,9 @@ static void show_rt_xsave_frame(struct xsave_struct *x)
pr_debug("-----------------------\n"); pr_debug("-----------------------\n");
} }
int restore_fpu(fpu_state_t *fpu_state, CoreEntry *core) int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
{ {
fpu_state_t *fpu_state = &sigframe->fpu_state;
struct xsave_struct *x = &fpu_state->xsave; struct xsave_struct *x = &fpu_state->xsave;
/* /*
......
...@@ -18,6 +18,6 @@ ...@@ -18,6 +18,6 @@
#define core_get_tls(pcore, ptls) #define core_get_tls(pcore, ptls)
int restore_fpu(fpu_state_t *fpu_state, CoreEntry *core); int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core);
#endif #endif
...@@ -21,7 +21,7 @@ int construct_sigframe(struct rt_sigframe *sigframe, ...@@ -21,7 +21,7 @@ int construct_sigframe(struct rt_sigframe *sigframe,
memset(blk_sigset, 0, sizeof(k_rtsigset_t)); memset(blk_sigset, 0, sizeof(k_rtsigset_t));
sigframe->fpu_state.has_fpu = true; sigframe->fpu_state.has_fpu = true;
if (restore_fpu(&sigframe->fpu_state, core)) if (restore_fpu(sigframe, core))
return -1; return -1;
if (sigframe->fpu_state.has_fpu) if (sigframe->fpu_state.has_fpu)
......
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