{
int err;
+++++ + /*
+++++ + * Clear the bytes not touched by the fxsave and reserved
+++++ + * for the SW usage.
+++++ + */
+++++ + err = __clear_user(&fx->sw_reserved,
+++++ + sizeof(struct _fpx_sw_bytes));
+++++ + if (unlikely(err))
+++++ + return -EFAULT;
+++++ +
asm volatile("1: rex64/fxsave (%[fx])\n\t"
"2:\n"
".section .fixup,\"ax\"\n"
memcpy(dst->state, src->state, xstate_size);
}
++++++extern void fpu_finit(struct fpu *fpu);
++++++
#endif /* __ASSEMBLY__ */
#define PSHUFB_XMM5_XMM0 .byte 0x66, 0x0f, 0x38, 0x00, 0xc5
#define FXSAVE_SIZE 512
++++++#define XSAVE_HDR_SIZE 64
++++++#define XSAVE_HDR_OFFSET FXSAVE_SIZE
++++++
++++++#define XSAVE_YMM_SIZE 256
++++++#define XSAVE_YMM_OFFSET (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET)
++++++
/*
* These are the features that the OS can handle currently.
*/
static inline int xsave_user(struct xsave_struct __user *buf)
{
int err;
+++++ +
+++++ + /*
+++++ + * Clear the xsave header first, so that reserved fields are
+++++ + * initialized to zero.
+++++ + */
+++++ + err = __clear_user(&buf->xsave_hdr,
+++++ + sizeof(struct xsave_hdr_struct));
+++++ + if (unlikely(err))
+++++ + return -EFAULT;
+++++ +
__asm__ __volatile__("1: .byte " REX_PREFIX "0x0f,0xae,0x27\n"
"2:\n"
".section .fixup,\"ax\"\n"
err = __copy_from_user(fx_sw_user, &buf->sw_reserved[0],
sizeof(struct _fpx_sw_bytes));
------
if (err)
------ return err;
++++++ return -EFAULT;
/*
* First Magic check failed.
*/
if (fx_sw_user->magic1 != FP_XSTATE_MAGIC1)
------ return -1;
++++++ return -EINVAL;
/*
* Check for error scenarios.
if (fx_sw_user->xstate_size < min_xstate_size ||
fx_sw_user->xstate_size > xstate_size ||
fx_sw_user->xstate_size > fx_sw_user->extended_size)
------ return -1;
++++++ return -EINVAL;
err = __get_user(magic2, (__u32 *) (((void *)fpstate) +
fx_sw_user->extended_size -
FP_XSTATE_MAGIC2_SIZE));
++++++ if (err)
++++++ return err;
/*
* Check for the presence of second magic word at the end of memory
* layout. This detects the case where the user just copied the legacy
* fpstate layout with out copying the extended state information
* in the memory layout.
*/
------ if (err || magic2 != FP_XSTATE_MAGIC2)
------ return -1;
++++++ if (magic2 != FP_XSTATE_MAGIC2)
++++++ return -EFAULT;
return 0;
}
return 0;
if (task_thread_info(tsk)->status & TS_USEDFPU) {
----- - /*
----- - * Start with clearing the user buffer. This will present a
----- - * clean context for the bytes not touched by the fxsave/xsave.
----- - */
----- - err = __clear_user(buf, sig_xstate_size);
----- - if (err)
----- - return err;
----- -
if (use_xsave())
err = xsave_user(buf);
else
* init the state skipped by the user.
*/
mask = pcntxt_mask & ~mask;
----- -
----- - xrstor_state(init_xstate_buf, mask);
+++++ + if (unlikely(mask))
+++++ + xrstor_state(init_xstate_buf, mask);
return 0;