Skip to content

Commit 49a91d6

Browse files
yyu-intel-comsuryasaimadhu
authored andcommitted
x86/fpu/xstate: Fix XSAVES offsets in setup_xstate_comp()
In setup_xstate_comp(), each XSAVES component offset starts from the end of its preceding component plus alignment. A disabled feature does not take space and its offset should be set to the end of its preceding one with no alignment. However, in this case, alignment is incorrectly added to the offset, which can cause the next component to have a wrong offset. This problem has not been visible because currently there is no xfeature requiring alignment. Fix it by tracking the next starting offset only from enabled xfeatures. To make it clear, also change the function name to setup_xstate_comp_offsets(). [ bp: Fix a typo in the comment above it, while at it. ] Signed-off-by: Yu-cheng Yu <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Reviewed-by: Dave Hansen <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent c12e13d commit 49a91d6

File tree

1 file changed

+12
-20
lines changed

1 file changed

+12
-20
lines changed

arch/x86/kernel/fpu/xstate.c

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -337,11 +337,11 @@ static int xfeature_is_aligned(int xfeature_nr)
337337
/*
338338
* This function sets up offsets and sizes of all extended states in
339339
* xsave area. This supports both standard format and compacted format
340-
* of the xsave aread.
340+
* of the xsave area.
341341
*/
342-
static void __init setup_xstate_comp(void)
342+
static void __init setup_xstate_comp_offsets(void)
343343
{
344-
unsigned int xstate_comp_sizes[XFEATURE_MAX];
344+
unsigned int next_offset;
345345
int i;
346346

347347
/*
@@ -355,31 +355,23 @@ static void __init setup_xstate_comp(void)
355355

356356
if (!boot_cpu_has(X86_FEATURE_XSAVES)) {
357357
for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
358-
if (xfeature_enabled(i)) {
358+
if (xfeature_enabled(i))
359359
xstate_comp_offsets[i] = xstate_offsets[i];
360-
xstate_comp_sizes[i] = xstate_sizes[i];
361-
}
362360
}
363361
return;
364362
}
365363

366-
xstate_comp_offsets[FIRST_EXTENDED_XFEATURE] =
367-
FXSAVE_SIZE + XSAVE_HDR_SIZE;
364+
next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE;
368365

369366
for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
370-
if (xfeature_enabled(i))
371-
xstate_comp_sizes[i] = xstate_sizes[i];
372-
else
373-
xstate_comp_sizes[i] = 0;
367+
if (!xfeature_enabled(i))
368+
continue;
374369

375-
if (i > FIRST_EXTENDED_XFEATURE) {
376-
xstate_comp_offsets[i] = xstate_comp_offsets[i-1]
377-
+ xstate_comp_sizes[i-1];
370+
if (xfeature_is_aligned(i))
371+
next_offset = ALIGN(next_offset, 64);
378372

379-
if (xfeature_is_aligned(i))
380-
xstate_comp_offsets[i] =
381-
ALIGN(xstate_comp_offsets[i], 64);
382-
}
373+
xstate_comp_offsets[i] = next_offset;
374+
next_offset += xstate_sizes[i];
383375
}
384376
}
385377

@@ -773,7 +765,7 @@ void __init fpu__init_system_xstate(void)
773765

774766
fpu__init_prepare_fx_sw_frame();
775767
setup_init_fpu_buf();
776-
setup_xstate_comp();
768+
setup_xstate_comp_offsets();
777769
print_xstate_offset_size();
778770

779771
pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n",

0 commit comments

Comments
 (0)