Skip to content

Commit 2848ff2

Browse files
chessturoKAGA-KOKO
authored andcommitted
x86/fpu: Avoid writing LBR bit to IA32_XSS unless supported
There are two distinct CPU features related to the use of XSAVES and LBR: whether LBR is itself supported and whether XSAVES supports LBR. The LBR subsystem correctly checks both in intel_pmu_arch_lbr_init(), but the XSTATE subsystem does not. The LBR bit is only removed from xfeatures_mask_independent when LBR is not supported by the CPU, but there is no validation of XSTATE support. If XSAVES does not support LBR the write to IA32_XSS causes a #GP fault, leaving the state of IA32_XSS unchanged, i.e. zero. The fault is handled with a warning and the boot continues. Consequently the next XRSTORS which tries to restore supervisor state fails with #GP because the RFBM has zero for all supervisor features, which does not match the XCOMP_BV field. As XFEATURE_MASK_FPSTATE includes supervisor features setting up the FPU causes a #GP, which ends up in fpu_reset_from_exception_fixup(). That fails due to the same problem resulting in recursive #GPs until the kernel runs out of stack space and double faults. Prevent this by storing the supported independent features in fpu_kernel_cfg during XSTATE initialization and use that cached value for retrieving the independent feature bits to be written into IA32_XSS. [ tglx: Massaged change log ] Fixes: f0dccc9 ("x86/fpu/xstate: Support dynamic supervisor feature for LBR") Suggested-by: Thomas Gleixner <[email protected]> Signed-off-by: Mitchell Levy <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/all/[email protected]
1 parent 0ecc5be commit 2848ff2

File tree

3 files changed

+12
-2
lines changed

3 files changed

+12
-2
lines changed

arch/x86/include/asm/fpu/types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,13 @@ struct fpu_state_config {
591591
* even without XSAVE support, i.e. legacy features FP + SSE
592592
*/
593593
u64 legacy_features;
594+
/*
595+
* @independent_features:
596+
*
597+
* Features that are supported by XSAVES, but not managed as part of
598+
* the FPU core, such as LBR
599+
*/
600+
u64 independent_features;
594601
};
595602

596603
/* FPU state configuration information */

arch/x86/kernel/fpu/xstate.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,9 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
788788
goto out_disable;
789789
}
790790

791+
fpu_kernel_cfg.independent_features = fpu_kernel_cfg.max_features &
792+
XFEATURE_MASK_INDEPENDENT;
793+
791794
/*
792795
* Clear XSAVE features that are disabled in the normal CPUID.
793796
*/

arch/x86/kernel/fpu/xstate.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ static inline u64 xfeatures_mask_supervisor(void)
6262
static inline u64 xfeatures_mask_independent(void)
6363
{
6464
if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
65-
return XFEATURE_MASK_INDEPENDENT & ~XFEATURE_MASK_LBR;
65+
return fpu_kernel_cfg.independent_features & ~XFEATURE_MASK_LBR;
6666

67-
return XFEATURE_MASK_INDEPENDENT;
67+
return fpu_kernel_cfg.independent_features;
6868
}
6969

7070
/* XSAVE/XRSTOR wrapper functions */

0 commit comments

Comments
 (0)