/* * If a processor implementation discern that a processor state component is * in its initialized state it may modify the corresponding bit in the * xsave_hdr.xstate_bv as '0', with out modifying the corresponding memory * layout in the case of xsaveopt. While presenting the xstate information to * the user, we always ensure that the memory layout of a feature will be in * the init state if the corresponding header bit is zero. This is to ensure * that the user doesn't see some stale state in the memory layout during * signal handling, debugging etc. */ void __sanitize_i387_state(struct task_struct *tsk) { u64 xstate_bv; int feature_bit = 0x2; struct i387_fxsave_struct *fx = &tsk->thread.fpu.state->fxsave; if (!fx) return; BUG_ON(__thread_has_fpu(tsk)); xstate_bv = tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv; /* * None of the feature bits are in init state. So nothing else * to do for us, as the memory layout is up to date. */ if ((xstate_bv & pcntxt_mask) == pcntxt_mask) return; /* * FP is in init state */ if (!(xstate_bv & XSTATE_FP)) { fx->cwd = 0x37f; fx->swd = 0; fx->twd = 0; fx->fop = 0; fx->rip = 0; fx->rdp = 0; memset(&fx->st_space[0], 0, 128); } /* * SSE is in init state */ if (!(xstate_bv & XSTATE_SSE)) memset(&fx->xmm_space[0], 0, 256); xstate_bv = (pcntxt_mask & ~xstate_bv) >> 2; /* * Update all the other memory layouts for which the corresponding * header bit is in the init state. */ while (xstate_bv) { if (xstate_bv & 0x1) { int offset = xstate_offsets[feature_bit]; int size = xstate_sizes[feature_bit]; memcpy(((void *) fx) + offset, ((void *) init_xstate_buf) + offset, size); } xstate_bv >>= 1; feature_bit++; } }
void __sanitize_i387_state(struct task_struct *tsk) { u64 xstate_bv; int feature_bit = 0x2; struct i387_fxsave_struct *fx = &tsk->thread.fpu.state->fxsave; if (!fx) return; BUG_ON(__thread_has_fpu(tsk)); xstate_bv = tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv; /* */ if ((xstate_bv & pcntxt_mask) == pcntxt_mask) return; /* */ if (!(xstate_bv & XSTATE_FP)) { fx->cwd = 0x37f; fx->swd = 0; fx->twd = 0; fx->fop = 0; fx->rip = 0; fx->rdp = 0; memset(&fx->st_space[0], 0, 128); } /* */ if (!(xstate_bv & XSTATE_SSE)) memset(&fx->xmm_space[0], 0, 256); xstate_bv = (pcntxt_mask & ~xstate_bv) >> 2; /* */ while (xstate_bv) { if (xstate_bv & 0x1) { int offset = xstate_offsets[feature_bit]; int size = xstate_sizes[feature_bit]; memcpy(((void *) fx) + offset, ((void *) init_xstate_buf) + offset, size); } xstate_bv >>= 1; feature_bit++; } }