Skip to content

Commit d6d6d50

Browse files
KAGA-KOKOsuryasaimadhu
authored andcommitted
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 <[email protected]> ] Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Link: https://lore.kernel.org/r/87o81pgbp2.ffs@tglx
1 parent 781c64b commit d6d6d50

File tree

1 file changed

+8
-41
lines changed

1 file changed

+8
-41
lines changed

arch/x86/kernel/fpu/xstate.c

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -385,25 +385,6 @@ static void __init setup_init_fpu_buf(void)
385385
fxsave(&init_fpstate.regs.fxsave);
386386
}
387387

388-
static int xfeature_uncompacted_offset(int xfeature_nr)
389-
{
390-
u32 eax, ebx, ecx, edx;
391-
392-
/*
393-
* Only XSAVES supports supervisor states and it uses compacted
394-
* format. Checking a supervisor state's uncompacted offset is
395-
* an error.
396-
*/
397-
if (XFEATURE_MASK_SUPERVISOR_ALL & BIT_ULL(xfeature_nr)) {
398-
WARN_ONCE(1, "No fixed offset for xstate %d\n", xfeature_nr);
399-
return -1;
400-
}
401-
402-
CHECK_XFEATURE(xfeature_nr);
403-
cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
404-
return ebx;
405-
}
406-
407388
int xfeature_size(int xfeature_nr)
408389
{
409390
u32 eax, ebx, ecx, edx;
@@ -581,29 +562,15 @@ static bool __init check_xstate_against_struct(int nr)
581562

582563
static unsigned int xstate_calculate_size(u64 xfeatures, bool compacted)
583564
{
584-
unsigned int size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
585-
int i;
565+
unsigned int topmost = fls64(xfeatures) - 1;
566+
unsigned int offset = xstate_offsets[topmost];
586567

587-
for_each_extended_xfeature(i, xfeatures) {
588-
/* Align from the end of the previous feature */
589-
if (xfeature_is_aligned64(i))
590-
size = ALIGN(size, 64);
591-
/*
592-
* In compacted format the enabled features are packed,
593-
* i.e. disabled features do not occupy space.
594-
*
595-
* In non-compacted format the offsets are fixed and
596-
* disabled states still occupy space in the memory buffer.
597-
*/
598-
if (!compacted)
599-
size = xfeature_uncompacted_offset(i);
600-
/*
601-
* Add the feature size even for non-compacted format
602-
* to make the end result correct
603-
*/
604-
size += xfeature_size(i);
605-
}
606-
return size;
568+
if (topmost <= XFEATURE_SSE)
569+
return sizeof(struct xregs_state);
570+
571+
if (compacted)
572+
offset = xfeature_get_offset(xfeatures, topmost);
573+
return offset + xstate_sizes[topmost];
607574
}
608575

609576
/*

0 commit comments

Comments
 (0)