Skip to content

Commit ea07400

Browse files
committed
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 <tglx@linutronix.de> Signed-off-by: Mitchell Levy <levymitchell0@gmail.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20240812-xsave-lbr-fix-v3-1-95bac1bf62f4@gmail.com
1 parent ffc2532 commit ea07400

3 files changed

Lines changed: 12 additions & 2 deletions

File tree

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

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

594601
/* FPU state configuration information */

arch/x86/kernel/fpu/xstate.c

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

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

arch/x86/kernel/fpu/xstate.h

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

69-
return XFEATURE_MASK_INDEPENDENT;
69+
return fpu_kernel_cfg.independent_features;
7070
}
7171

7272
/* XSAVE/XRSTOR wrapper functions */

0 commit comments

Comments
 (0)