Commit 3f7f7563 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Borislav Petkov

x86/fpu: Use copy_xstate_to_uabi_buf() in fpregs_get()

Use the new functionality of copy_xstate_to_uabi_buf() to retrieve the
FX state when XSAVE* is in use. This avoids to overwrite the FPU state
buffer with fpstate_sanitize_xstate() which is error prone and duplicated
code.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Reviewed-by: default avatarBorislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20210623121453.014441775@linutronix.de
parent adc997b3
...@@ -210,10 +210,10 @@ static inline u32 twd_fxsr_to_i387(struct fxregs_state *fxsave) ...@@ -210,10 +210,10 @@ static inline u32 twd_fxsr_to_i387(struct fxregs_state *fxsave)
* FXSR floating point environment conversions. * FXSR floating point environment conversions.
*/ */
void static void __convert_from_fxsr(struct user_i387_ia32_struct *env,
convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk) struct task_struct *tsk,
struct fxregs_state *fxsave)
{ {
struct fxregs_state *fxsave = &tsk->thread.fpu.state.fxsave;
struct _fpreg *to = (struct _fpreg *) &env->st_space[0]; struct _fpreg *to = (struct _fpreg *) &env->st_space[0];
struct _fpxreg *from = (struct _fpxreg *) &fxsave->st_space[0]; struct _fpxreg *from = (struct _fpxreg *) &fxsave->st_space[0];
int i; int i;
...@@ -247,6 +247,12 @@ convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk) ...@@ -247,6 +247,12 @@ convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
memcpy(&to[i], &from[i], sizeof(to[0])); memcpy(&to[i], &from[i], sizeof(to[0]));
} }
void
convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
{
__convert_from_fxsr(env, tsk, &tsk->thread.fpu.state.fxsave);
}
void convert_to_fxsr(struct fxregs_state *fxsave, void convert_to_fxsr(struct fxregs_state *fxsave,
const struct user_i387_ia32_struct *env) const struct user_i387_ia32_struct *env)
...@@ -279,25 +285,29 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset, ...@@ -279,25 +285,29 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset,
{ {
struct fpu *fpu = &target->thread.fpu; struct fpu *fpu = &target->thread.fpu;
struct user_i387_ia32_struct env; struct user_i387_ia32_struct env;
struct fxregs_state fxsave, *fx;
fpu__prepare_read(fpu); fpu__prepare_read(fpu);
if (!boot_cpu_has(X86_FEATURE_FPU)) if (!cpu_feature_enabled(X86_FEATURE_FPU))
return fpregs_soft_get(target, regset, to); return fpregs_soft_get(target, regset, to);
if (!boot_cpu_has(X86_FEATURE_FXSR)) { if (!cpu_feature_enabled(X86_FEATURE_FXSR)) {
return membuf_write(&to, &fpu->state.fsave, return membuf_write(&to, &fpu->state.fsave,
sizeof(struct fregs_state)); sizeof(struct fregs_state));
} }
fpstate_sanitize_xstate(fpu); if (use_xsave()) {
struct membuf mb = { .p = &fxsave, .left = sizeof(fxsave) };
if (to.left == sizeof(env)) { /* Handle init state optimized xstate correctly */
convert_from_fxsr(to.p, target); copy_xstate_to_uabi_buf(mb, &fpu->state.xsave, XSTATE_COPY_FP);
return 0; fx = &fxsave;
} else {
fx = &fpu->state.fxsave;
} }
convert_from_fxsr(&env, target); __convert_from_fxsr(&env, target, fx);
return membuf_write(&to, &env, sizeof(env)); return membuf_write(&to, &env, sizeof(env));
} }
......
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