staticinlinevoid xstate_init_xcomp_bv(struct xregs_state *xsave, u64 mask)
{ /* * XRSTORS requires these bits set in xcomp_bv, or it will * trigger #GP:
*/ if (cpu_feature_enabled(X86_FEATURE_XCOMPACTED))
xsave->header.xcomp_bv = mask | XCOMP_BV_COMPACTED_FORMAT;
}
/* Read the xfeatures value already saved in the user buffer */
err = __get_user(xfeatures, &xbuf->header.xfeatures);
xfeatures |= mask;
err |= __put_user(xfeatures, &xbuf->header.xfeatures);
return err;
}
/* * Update the value of PKRU register that was already pushed onto the signal frame.
*/ staticinlineint update_pkru_in_sigframe(struct xregs_state __user *buf, u32 pkru)
{ int err;
if (unlikely(!cpu_feature_enabled(X86_FEATURE_OSPKE))) return 0;
/* Mark PKRU as in-use so that it is restored correctly. */
err = set_xfeature_in_sigframe(buf, XFEATURE_MASK_PKRU); if (err) return err;
/* Update PKRU value in the userspace xsave buffer. */ return __put_user(pkru, (unsignedint __user *)get_xsave_addr_user(buf, XFEATURE_PKRU));
}
/* * After this @err contains 0 on success or the trap number when the * operation raises an exception. * * The [xa] input parameter below represents the struct xregs_state pointer * and the asm symbolic name for the argument used in the XSAVE/XRSTOR insns * above.
*/ #define XSTATE_OP(op, st, lmask, hmask, err) \ asmvolatile("1:" op "\n\t" \ "xor %[err], %[err]\n" \ "2:\n" \
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_MCE_SAFE) \
: [err] "=a" (err) \
: [xa] "m" (*(st)), "a" (lmask), "d" (hmask) \
: "memory")
/* * If XSAVES is enabled, it replaces XSAVEC because it supports supervisor * states in addition to XSAVEC. * * Otherwise if XSAVEC is enabled, it replaces XSAVEOPT because it supports * compacted storage format in addition to XSAVEOPT. * * Otherwise, if XSAVEOPT is enabled, XSAVEOPT replaces XSAVE because XSAVEOPT * supports modified optimization which is not supported by XSAVE. * * Use XSAVE as a fallback.
*/ #define XSTATE_XSAVE(st, lmask, hmask, err) \ asmvolatile("1: " ALTERNATIVE_3(XSAVE, \
XSAVEOPT, X86_FEATURE_XSAVEOPT, \
XSAVEC, X86_FEATURE_XSAVEC, \
XSAVES, X86_FEATURE_XSAVES) \ "\n\t" \ "xor %[err], %[err]\n" \ "3:\n" \
_ASM_EXTABLE_TYPE_REG(1b, 3b, EX_TYPE_EFAULT_REG, %[err]) \
: [err] "=r" (err) \
: [xa] "m" (*(st)), "a" (lmask), "d" (hmask) \
: "memory")
/* * Use XRSTORS to restore context if it is enabled. XRSTORS supports compact * XSAVE area format.
*/ #define XSTATE_XRESTORE(st, lmask, hmask) \ asmvolatile("1: " ALTERNATIVE(XRSTOR, \
XRSTORS, X86_FEATURE_XSAVES) \ "\n" \ "3:\n" \
_ASM_EXTABLE_TYPE(1b, 3b, EX_TYPE_FPU_RESTORE) \
: \
: [xa] "m" (*(st)), "a" (lmask), "d" (hmask) \
: "memory")
/* * Save processor xstate to xsave area. * * Uses either XSAVE or XSAVEOPT or XSAVES depending on the CPU features * and command line options. The choice is permanent until the next reboot.
*/ staticinlinevoid os_xsave(struct fpstate *fpstate)
{
u64 mask = fpstate->xfeatures;
u32 lmask = mask;
u32 hmask = mask >> 32; int err;
/* * XSAVE itself always writes all requested xfeatures. Removing features * from the request bitmap reduces the features which are written. * Generate a mask of features which must be written to a sigframe. The * unset features can be optimized away and not written. * * This optimization is user-visible. Only use for states where * uninitialized sigframe contents are tolerable, like dynamic features. * * Users of buffers produced with this optimization must check XSTATE_BV * to determine which features have been optimized out.
*/ staticinline u64 xfeatures_need_sigframe_write(void)
{
u64 xfeaures_to_write;
/* In-use features must be written: */
xfeaures_to_write = xfeatures_in_use();
/* Also write all non-optimizable sigframe features: */
xfeaures_to_write |= XFEATURE_MASK_USER_SUPPORTED &
~XFEATURE_MASK_SIGFRAME_INITOPT;
return xfeaures_to_write;
}
/* * Save xstate to user space xsave area. * * We don't use modified optimization because xrstor/xrstors might track * a different application. * * We don't use compacted format xsave area for backward compatibility for * old applications which don't understand the compacted format of the * xsave area. * * The caller has to zero buf::header before calling this because XSAVE* * does not touch the reserved fields in the header.
*/ staticinlineint xsave_to_user_sigframe(struct xregs_state __user *buf, u32 pkru)
{ /* * Include the features which are not xsaved/rstored by the kernel * internally, e.g. PKRU. That's user space ABI and also required * to allow the signal handler to modify PKRU.
*/ struct fpstate *fpstate = x86_task_fpu(current)->fpstate;
u64 mask = fpstate->user_xfeatures;
u32 lmask;
u32 hmask; int err;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.