Commit 49e4eb41 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Borislav Petkov

x86/fpu/xstate: Use fpstate for copy_uabi_to_xstate()

Prepare for dynamically enabled states per task. The function needs to
retrieve the features and sizes which are valid in a fpstate
context. Retrieve them from fpstate.

Move the function declarations to the core header as they are not
required anywhere else.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20211013145323.233529986@linutronix.de
parent 3ac8d757
...@@ -129,20 +129,8 @@ extern void __init update_regset_xstate_info(unsigned int size, ...@@ -129,20 +129,8 @@ extern void __init update_regset_xstate_info(unsigned int size,
u64 xstate_mask); u64 xstate_mask);
int xfeature_size(int xfeature_nr); int xfeature_size(int xfeature_nr);
int copy_uabi_from_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf);
int copy_sigframe_from_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf);
void xsaves(struct xregs_state *xsave, u64 mask); void xsaves(struct xregs_state *xsave, u64 mask);
void xrstors(struct xregs_state *xsave, u64 mask); void xrstors(struct xregs_state *xsave, u64 mask);
enum xstate_copy_mode {
XSTATE_COPY_FP,
XSTATE_COPY_FX,
XSTATE_COPY_XSAVE,
};
struct membuf;
void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk,
enum xstate_copy_mode mode);
#endif #endif
...@@ -222,7 +222,7 @@ int fpu_copy_kvm_uabi_to_fpstate(struct fpu *fpu, const void *buf, u64 xcr0, ...@@ -222,7 +222,7 @@ int fpu_copy_kvm_uabi_to_fpstate(struct fpu *fpu, const void *buf, u64 xcr0,
if (ustate->xsave.header.xfeatures & ~xcr0) if (ustate->xsave.header.xfeatures & ~xcr0)
return -EINVAL; return -EINVAL;
ret = copy_uabi_from_kernel_to_xstate(&kstate->regs.xsave, ustate); ret = copy_uabi_from_kernel_to_xstate(kstate, ustate);
if (ret) if (ret)
return ret; return ret;
......
...@@ -8,11 +8,11 @@ ...@@ -8,11 +8,11 @@
#include <asm/fpu/api.h> #include <asm/fpu/api.h>
#include <asm/fpu/signal.h> #include <asm/fpu/signal.h>
#include <asm/fpu/regset.h> #include <asm/fpu/regset.h>
#include <asm/fpu/xstate.h>
#include "context.h" #include "context.h"
#include "internal.h" #include "internal.h"
#include "legacy.h" #include "legacy.h"
#include "xstate.h"
/* /*
* The xstateregs_active() routine is the same as the regset_fpregs_active() routine, * The xstateregs_active() routine is the same as the regset_fpregs_active() routine,
...@@ -168,8 +168,7 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, ...@@ -168,8 +168,7 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
} }
fpu_force_restore(fpu); fpu_force_restore(fpu);
ret = copy_uabi_from_kernel_to_xstate(&fpu->fpstate->regs.xsave, ret = copy_uabi_from_kernel_to_xstate(fpu->fpstate, kbuf ?: tmpbuf);
kbuf ?: tmpbuf);
out: out:
vfree(tmpbuf); vfree(tmpbuf);
......
...@@ -375,7 +375,7 @@ static bool __fpu_restore_sig(void __user *buf, void __user *buf_fx, ...@@ -375,7 +375,7 @@ static bool __fpu_restore_sig(void __user *buf, void __user *buf_fx,
fpregs = &fpu->fpstate->regs; fpregs = &fpu->fpstate->regs;
if (use_xsave() && !fx_only) { if (use_xsave() && !fx_only) {
if (copy_sigframe_from_user_to_xstate(&fpregs->xsave, buf_fx)) if (copy_sigframe_from_user_to_xstate(fpu->fpstate, buf_fx))
return false; return false;
} else { } else {
if (__copy_from_user(&fpregs->fxsave, buf_fx, if (__copy_from_user(&fpregs->fxsave, buf_fx,
......
...@@ -463,10 +463,11 @@ int xfeature_size(int xfeature_nr) ...@@ -463,10 +463,11 @@ int xfeature_size(int xfeature_nr)
} }
/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */ /* Validate an xstate header supplied by userspace (ptrace or sigreturn) */
static int validate_user_xstate_header(const struct xstate_header *hdr) static int validate_user_xstate_header(const struct xstate_header *hdr,
struct fpstate *fpstate)
{ {
/* No unknown or supervisor features may be set */ /* No unknown or supervisor features may be set */
if (hdr->xfeatures & ~xfeatures_mask_uabi()) if (hdr->xfeatures & ~fpstate->user_xfeatures)
return -EINVAL; return -EINVAL;
/* Userspace must use the uncompacted format */ /* Userspace must use the uncompacted format */
...@@ -1115,9 +1116,10 @@ static int copy_from_buffer(void *dst, unsigned int offset, unsigned int size, ...@@ -1115,9 +1116,10 @@ static int copy_from_buffer(void *dst, unsigned int offset, unsigned int size,
} }
static int copy_uabi_to_xstate(struct xregs_state *xsave, const void *kbuf, static int copy_uabi_to_xstate(struct fpstate *fpstate, const void *kbuf,
const void __user *ubuf) const void __user *ubuf)
{ {
struct xregs_state *xsave = &fpstate->regs.xsave;
unsigned int offset, size; unsigned int offset, size;
struct xstate_header hdr; struct xstate_header hdr;
u64 mask; u64 mask;
...@@ -1127,7 +1129,7 @@ static int copy_uabi_to_xstate(struct xregs_state *xsave, const void *kbuf, ...@@ -1127,7 +1129,7 @@ static int copy_uabi_to_xstate(struct xregs_state *xsave, const void *kbuf,
if (copy_from_buffer(&hdr, offset, sizeof(hdr), kbuf, ubuf)) if (copy_from_buffer(&hdr, offset, sizeof(hdr), kbuf, ubuf))
return -EFAULT; return -EFAULT;
if (validate_user_xstate_header(&hdr)) if (validate_user_xstate_header(&hdr, fpstate))
return -EINVAL; return -EINVAL;
/* Validate MXCSR when any of the related features is in use */ /* Validate MXCSR when any of the related features is in use */
...@@ -1182,9 +1184,9 @@ static int copy_uabi_to_xstate(struct xregs_state *xsave, const void *kbuf, ...@@ -1182,9 +1184,9 @@ static int copy_uabi_to_xstate(struct xregs_state *xsave, const void *kbuf,
* Convert from a ptrace standard-format kernel buffer to kernel XSAVE[S] * Convert from a ptrace standard-format kernel buffer to kernel XSAVE[S]
* format and copy to the target thread. Used by ptrace and KVM. * format and copy to the target thread. Used by ptrace and KVM.
*/ */
int copy_uabi_from_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf) int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf)
{ {
return copy_uabi_to_xstate(xsave, kbuf, NULL); return copy_uabi_to_xstate(fpstate, kbuf, NULL);
} }
/* /*
...@@ -1192,10 +1194,10 @@ int copy_uabi_from_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf) ...@@ -1192,10 +1194,10 @@ int copy_uabi_from_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf)
* XSAVE[S] format and copy to the target thread. This is called from the * XSAVE[S] format and copy to the target thread. This is called from the
* sigreturn() and rt_sigreturn() system calls. * sigreturn() and rt_sigreturn() system calls.
*/ */
int copy_sigframe_from_user_to_xstate(struct xregs_state *xsave, int copy_sigframe_from_user_to_xstate(struct fpstate *fpstate,
const void __user *ubuf) const void __user *ubuf)
{ {
return copy_uabi_to_xstate(xsave, NULL, ubuf); return copy_uabi_to_xstate(fpstate, NULL, ubuf);
} }
static bool validate_independent_components(u64 mask) static bool validate_independent_components(u64 mask)
......
...@@ -15,8 +15,20 @@ static inline void xstate_init_xcomp_bv(struct xregs_state *xsave, u64 mask) ...@@ -15,8 +15,20 @@ static inline void xstate_init_xcomp_bv(struct xregs_state *xsave, u64 mask)
xsave->header.xcomp_bv = mask | XCOMP_BV_COMPACTED_FORMAT; xsave->header.xcomp_bv = mask | XCOMP_BV_COMPACTED_FORMAT;
} }
enum xstate_copy_mode {
XSTATE_COPY_FP,
XSTATE_COPY_FX,
XSTATE_COPY_XSAVE,
};
struct membuf;
extern void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate, extern void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate,
u32 pkru_val, enum xstate_copy_mode copy_mode); u32 pkru_val, enum xstate_copy_mode copy_mode);
extern void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk,
enum xstate_copy_mode mode);
extern int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf);
extern int copy_sigframe_from_user_to_xstate(struct fpstate *fpstate, const void __user *ubuf);
extern void fpu__init_cpu_xstate(void); extern void fpu__init_cpu_xstate(void);
extern void fpu__init_system_xstate(void); extern void fpu__init_system_xstate(void);
......
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