mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-09 08:09:12 +00:00
x86/fpu/xstate: Add helpers for LBR dynamic supervisor feature
The perf subsystem will only need to save/restore the LBR state. However, the existing helpers save all supported supervisor states to a kernel buffer, which will be unnecessary. Two helpers are introduced to only save/restore requested dynamic supervisor states. The supervisor features in XFEATURE_MASK_SUPERVISOR_SUPPORTED and XFEATURE_MASK_SUPERVISOR_UNSUPPORTED mask cannot be saved/restored using these helpers. The helpers will be used in the following patch. Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Dave Hansen <dave.hansen@intel.com> Link: https://lkml.kernel.org/r/1593780569-62993-22-git-send-email-kan.liang@linux.intel.com
This commit is contained in:
parent
f0dccc9da4
commit
50f408d96d
2 changed files with 75 additions and 0 deletions
|
@ -106,6 +106,9 @@ int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned i
|
||||||
int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf);
|
int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf);
|
||||||
int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf);
|
int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf);
|
||||||
void copy_supervisor_to_kernel(struct xregs_state *xsave);
|
void copy_supervisor_to_kernel(struct xregs_state *xsave);
|
||||||
|
void copy_dynamic_supervisor_to_kernel(struct xregs_state *xstate, u64 mask);
|
||||||
|
void copy_kernel_to_dynamic_supervisor(struct xregs_state *xstate, u64 mask);
|
||||||
|
|
||||||
|
|
||||||
/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */
|
/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */
|
||||||
int validate_user_xstate_header(const struct xstate_header *hdr);
|
int validate_user_xstate_header(const struct xstate_header *hdr);
|
||||||
|
|
|
@ -1361,6 +1361,78 @@ void copy_supervisor_to_kernel(struct xregs_state *xstate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy_dynamic_supervisor_to_kernel() - Save dynamic supervisor states to
|
||||||
|
* an xsave area
|
||||||
|
* @xstate: A pointer to an xsave area
|
||||||
|
* @mask: Represent the dynamic supervisor features saved into the xsave area
|
||||||
|
*
|
||||||
|
* Only the dynamic supervisor states sets in the mask are saved into the xsave
|
||||||
|
* area (See the comment in XFEATURE_MASK_DYNAMIC for the details of dynamic
|
||||||
|
* supervisor feature). Besides the dynamic supervisor states, the legacy
|
||||||
|
* region and XSAVE header are also saved into the xsave area. The supervisor
|
||||||
|
* features in the XFEATURE_MASK_SUPERVISOR_SUPPORTED and
|
||||||
|
* XFEATURE_MASK_SUPERVISOR_UNSUPPORTED are not saved.
|
||||||
|
*
|
||||||
|
* The xsave area must be 64-bytes aligned.
|
||||||
|
*/
|
||||||
|
void copy_dynamic_supervisor_to_kernel(struct xregs_state *xstate, u64 mask)
|
||||||
|
{
|
||||||
|
u64 dynamic_mask = xfeatures_mask_dynamic() & mask;
|
||||||
|
u32 lmask, hmask;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (WARN_ON_FPU(!boot_cpu_has(X86_FEATURE_XSAVES)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (WARN_ON_FPU(!dynamic_mask))
|
||||||
|
return;
|
||||||
|
|
||||||
|
lmask = dynamic_mask;
|
||||||
|
hmask = dynamic_mask >> 32;
|
||||||
|
|
||||||
|
XSTATE_OP(XSAVES, xstate, lmask, hmask, err);
|
||||||
|
|
||||||
|
/* Should never fault when copying to a kernel buffer */
|
||||||
|
WARN_ON_FPU(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy_kernel_to_dynamic_supervisor() - Restore dynamic supervisor states from
|
||||||
|
* an xsave area
|
||||||
|
* @xstate: A pointer to an xsave area
|
||||||
|
* @mask: Represent the dynamic supervisor features restored from the xsave area
|
||||||
|
*
|
||||||
|
* Only the dynamic supervisor states sets in the mask are restored from the
|
||||||
|
* xsave area (See the comment in XFEATURE_MASK_DYNAMIC for the details of
|
||||||
|
* dynamic supervisor feature). Besides the dynamic supervisor states, the
|
||||||
|
* legacy region and XSAVE header are also restored from the xsave area. The
|
||||||
|
* supervisor features in the XFEATURE_MASK_SUPERVISOR_SUPPORTED and
|
||||||
|
* XFEATURE_MASK_SUPERVISOR_UNSUPPORTED are not restored.
|
||||||
|
*
|
||||||
|
* The xsave area must be 64-bytes aligned.
|
||||||
|
*/
|
||||||
|
void copy_kernel_to_dynamic_supervisor(struct xregs_state *xstate, u64 mask)
|
||||||
|
{
|
||||||
|
u64 dynamic_mask = xfeatures_mask_dynamic() & mask;
|
||||||
|
u32 lmask, hmask;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (WARN_ON_FPU(!boot_cpu_has(X86_FEATURE_XSAVES)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (WARN_ON_FPU(!dynamic_mask))
|
||||||
|
return;
|
||||||
|
|
||||||
|
lmask = dynamic_mask;
|
||||||
|
hmask = dynamic_mask >> 32;
|
||||||
|
|
||||||
|
XSTATE_OP(XRSTORS, xstate, lmask, hmask, err);
|
||||||
|
|
||||||
|
/* Should never fault when copying from a kernel buffer */
|
||||||
|
WARN_ON_FPU(err);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_PID_ARCH_STATUS
|
#ifdef CONFIG_PROC_PID_ARCH_STATUS
|
||||||
/*
|
/*
|
||||||
* Report the amount of time elapsed in millisecond since last AVX512
|
* Report the amount of time elapsed in millisecond since last AVX512
|
||||||
|
|
Loading…
Add table
Reference in a new issue