@@ -156,16 +156,32 @@ void fpu__init_cpu_xstate(void)
}
}
+/* Can the XSAVE architecture be used to manage this feature? */
static bool xfeature_enabled(enum xfeature xfeature)
{
return xfeatures_mask_all & BIT_ULL(xfeature);
}
/*
+ * Is space for the feature present in the task->thread.fpu
+ * fpstate buffer and is the using XSAVE to context-switch it?
+ */
+static bool xfeature_fpstate_enabled(enum xfeature xfeature)
+{
+ // For bisectability, mirror xfeature_enabled() for now.
+ //return xfeatures_mask_fpstate() & BIT_ULL(xfeature);
+ return xfeature_enabled(xfeature);
+}
+
+/*
* Record the offsets and sizes of various xstates contained
- * in the XSAVE state memory layout.
+ * in the non-compacted XSAVE state memory layout.
+ *
+ * These are always used in the XSAVE ABIs and are used for
+ * the kernel xstate buffer in cases where XSAVES (and thus
+ * the compacted format) is not supported.
*/
-static void __init setup_xstate_features(void)
+static void __init setup_xfeature_offsets(void)
{
u32 eax, ebx, ecx, edx, i;
/* start at the beginning of the "extended state" */
@@ -185,6 +201,10 @@ static void __init setup_xstate_features
xmm_space);
for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
+ /*
+ * Set up any features enabled that are in the kernel
+ * xstate buffer *or* the user XSAVE ABIs.
+ */
if (!xfeature_enabled(i))
continue;
@@ -257,7 +277,7 @@ static int xfeature_is_aligned(int xfeat
CHECK_XFEATURE(xfeature_nr);
- if (!xfeature_enabled(xfeature_nr)) {
+ if (!xfeature_fpstate_enabled(xfeature_nr)) {
WARN_ONCE(1, "Checking alignment of disabled xfeature %d\n",
xfeature_nr);
return 0;
@@ -293,7 +313,7 @@ static void __init setup_xstate_comp_off
if (!boot_cpu_has(X86_FEATURE_XSAVES)) {
for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
- if (xfeature_enabled(i))
+ if (xfeature_fpstate_enabled(i))
xstate_comp_offsets[i] = xstate_offsets[i];
}
return;
@@ -302,7 +322,7 @@ static void __init setup_xstate_comp_off
next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE;
for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
- if (!xfeature_enabled(i))
+ if (!xfeature_fpstate_enabled(i))
continue;
if (xfeature_is_aligned(i))
@@ -329,7 +349,7 @@ static void __init setup_supervisor_only
next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE;
for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
- if (!xfeature_enabled(i) || !xfeature_is_supervisor(i))
+ if (!xfeature_fpstate_enabled(i) || !xfeature_is_supervisor(i))
continue;
if (xfeature_is_aligned(i))
@@ -348,7 +368,7 @@ static void __init print_xstate_offset_s
int i;
for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
- if (!xfeature_enabled(i))
+ if (!xfeature_fpstate_enabled(i))
continue;
pr_info("x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n",
i, xstate_comp_offsets[i], i, xstate_sizes[i]);
@@ -391,7 +411,7 @@ static void __init setup_init_fpu_buf(vo
if (!boot_cpu_has(X86_FEATURE_XSAVE))
return;
- setup_xstate_features();
+ setup_xfeature_offsets();
print_xstate_features();
if (boot_cpu_has(X86_FEATURE_XSAVES))
@@ -562,7 +582,7 @@ static void do_extra_xstate_size_checks(
int i;
for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
- if (!xfeature_enabled(i))
+ if (!xfeature_fpstate_enabled(i))
continue;
check_xstate_against_struct(i);
@@ -849,7 +869,7 @@ void fpu__resume_cpu(void)
*/
static void *__raw_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
{
- if (!xfeature_enabled(xfeature_nr)) {
+ if (!xfeature_fpstate_enabled(xfeature_nr)) {
WARN_ON_FPU(1);
return NULL;
}