Commit d6d6d50f authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Borislav Petkov

x86/fpu/xstate: Consolidate size calculations

Use the offset calculation to do the size calculation which avoids yet
another series of CPUID instructions for each invocation.

  [ Fix the FP/SSE only case which missed to take the xstate
    header into account, as
    Reported-by: kernel test robot <oliver.sang@intel.com> ]
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/r/87o81pgbp2.ffs@tglx
parent 781c64bf
...@@ -385,25 +385,6 @@ static void __init setup_init_fpu_buf(void) ...@@ -385,25 +385,6 @@ static void __init setup_init_fpu_buf(void)
fxsave(&init_fpstate.regs.fxsave); fxsave(&init_fpstate.regs.fxsave);
} }
static int xfeature_uncompacted_offset(int xfeature_nr)
{
u32 eax, ebx, ecx, edx;
/*
* Only XSAVES supports supervisor states and it uses compacted
* format. Checking a supervisor state's uncompacted offset is
* an error.
*/
if (XFEATURE_MASK_SUPERVISOR_ALL & BIT_ULL(xfeature_nr)) {
WARN_ONCE(1, "No fixed offset for xstate %d\n", xfeature_nr);
return -1;
}
CHECK_XFEATURE(xfeature_nr);
cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
return ebx;
}
int xfeature_size(int xfeature_nr) int xfeature_size(int xfeature_nr)
{ {
u32 eax, ebx, ecx, edx; u32 eax, ebx, ecx, edx;
...@@ -581,29 +562,15 @@ static bool __init check_xstate_against_struct(int nr) ...@@ -581,29 +562,15 @@ static bool __init check_xstate_against_struct(int nr)
static unsigned int xstate_calculate_size(u64 xfeatures, bool compacted) static unsigned int xstate_calculate_size(u64 xfeatures, bool compacted)
{ {
unsigned int size = FXSAVE_SIZE + XSAVE_HDR_SIZE; unsigned int topmost = fls64(xfeatures) - 1;
int i; unsigned int offset = xstate_offsets[topmost];
for_each_extended_xfeature(i, xfeatures) { if (topmost <= XFEATURE_SSE)
/* Align from the end of the previous feature */ return sizeof(struct xregs_state);
if (xfeature_is_aligned64(i))
size = ALIGN(size, 64); if (compacted)
/* offset = xfeature_get_offset(xfeatures, topmost);
* In compacted format the enabled features are packed, return offset + xstate_sizes[topmost];
* i.e. disabled features do not occupy space.
*
* In non-compacted format the offsets are fixed and
* disabled states still occupy space in the memory buffer.
*/
if (!compacted)
size = xfeature_uncompacted_offset(i);
/*
* Add the feature size even for non-compacted format
* to make the end result correct
*/
size += xfeature_size(i);
}
return size;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment