mirror of
https://github.com/torvalds/linux.git
synced 2026-10-24 16:55:02 +02:00
x86/fpu: Use get_user()/put_user() for the signal frame fields
The FPU signal frame code reads and writes a handful of individual fields (the xstate magic words, the legacy status word, the xfeatures header and PKRU) with __get_user() and __put_user(). These rely on an access_ok() of the whole frame done earlier by the caller. Each of those accesses enables and disables user access on its own, so the up-front check saves nothing. On x86, __get_user() is even more expensive than get_user(): it does an lfence, where get_user() checks the address with a couple of plain instructions. Use get_user() and put_user(). The accesses that run with page faults disabled stay that way; get_user() and put_user() are fine there. This is part of getting rid of __get_user() and __put_user() entirely. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
05c6ad3f3b
commit
a7de2d2d78
|
|
@ -48,7 +48,7 @@ static inline bool check_xstate_in_sigframe(struct fxregs_state __user *fxbuf,
|
|||
* fpstate layout with out copying the extended state information
|
||||
* in the memory layout.
|
||||
*/
|
||||
if (__get_user(magic2, (__u32 __user *)(fpstate + fx_sw->xstate_size)))
|
||||
if (get_user(magic2, (__u32 __user *)(fpstate + fx_sw->xstate_size)))
|
||||
return false;
|
||||
|
||||
if (likely(magic2 == FP_XSTATE_MAGIC2))
|
||||
|
|
@ -81,14 +81,14 @@ static inline bool save_fsave_header(struct task_struct *tsk, void __user *buf)
|
|||
convert_from_fxsr(&env, tsk);
|
||||
|
||||
if (__copy_to_user(buf, &env, sizeof(env)) ||
|
||||
__put_user(xsave->i387.swd, &fp->status) ||
|
||||
__put_user(X86_FXSR_MAGIC, &fp->magic))
|
||||
put_user(xsave->i387.swd, &fp->status) ||
|
||||
put_user(X86_FXSR_MAGIC, &fp->magic))
|
||||
return false;
|
||||
} else {
|
||||
struct fregs_state __user *fp = buf;
|
||||
u32 swd;
|
||||
|
||||
if (__get_user(swd, &fp->swd) || __put_user(swd, &fp->status))
|
||||
if (get_user(swd, &fp->swd) || put_user(swd, &fp->status))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -128,8 +128,8 @@ static inline bool save_xstate_epilog(void __user *buf, int ia32_frame,
|
|||
if (!use_xsave())
|
||||
return !err;
|
||||
|
||||
err |= __put_user(FP_XSTATE_MAGIC2,
|
||||
(__u32 __user *)(buf + fpstate->user_size));
|
||||
err |= put_user(FP_XSTATE_MAGIC2,
|
||||
(__u32 __user *)(buf + fpstate->user_size));
|
||||
|
||||
/*
|
||||
* For legacy compatible, we always set FP/SSE bits in the bit
|
||||
|
|
|
|||
|
|
@ -76,9 +76,9 @@ static inline int set_xfeature_in_sigframe(struct xregs_state __user *xbuf, u64
|
|||
int err;
|
||||
|
||||
/* Read the xfeatures value already saved in the user buffer */
|
||||
err = __get_user(xfeatures, &xbuf->header.xfeatures);
|
||||
err = get_user(xfeatures, &xbuf->header.xfeatures);
|
||||
xfeatures |= mask;
|
||||
err |= __put_user(xfeatures, &xbuf->header.xfeatures);
|
||||
err |= put_user(xfeatures, &xbuf->header.xfeatures);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ static inline int update_pkru_in_sigframe(struct xregs_state __user *buf, u32 pk
|
|||
return err;
|
||||
|
||||
/* Update PKRU value in the userspace xsave buffer. */
|
||||
return __put_user(pkru, (unsigned int __user *)get_xsave_addr_user(buf, XFEATURE_PKRU));
|
||||
return put_user(pkru, (unsigned int __user *)get_xsave_addr_user(buf, XFEATURE_PKRU));
|
||||
}
|
||||
|
||||
/* XSAVE/XRSTOR wrapper functions */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user