x86/xstate: Fix initialisation of XSS cache

The clobbering of this_cpu(xcr0) and this_cpu(xss) to architecturally invalid
values is to force the subsequent set_xcr0() and set_msr_xss() to reload the
hardware register.

While XCR0 is reloaded in xstate_init(), MSR_XSS isn't.  This causes
get_msr_xss() to return the invalid value, and logic of the form:

    old = get_msr_xss();
    set_msr_xss(new);
    ...
    set_msr_xss(old);

to try and restore said invalid value.

The architecturally invalid value must be purged from the cache, meaning the
hardware register must be written at least once.  This in turn highlights that
the invalid value must only be used in the case that the hardware register is
available.

Fixes: f7f4a52392 ("x86/xstate: reset cached register values on resume")
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
master commit: 9e6dbbe8bf
master date: 2024-06-19 13:00:06 +0100
This commit is contained in:
Andrew Cooper authored and Jan Beulich committed 2024-06-26 14:13:17 +02:00
1 parent 9dfe294cb6
commit 80fe1fe2fe
1 file changed
+11 -7
+11 -7
View File
@@ -642,13 +642,6 @@ void xstate_init(struct cpuinfo_x86 *c)
return;
}
/*
* Zap the cached values to make set_xcr0() and set_msr_xss() really
* write it.
*/
this_cpu(xcr0) = 0;
this_cpu(xss) = ~0;
cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
feature_mask = (((u64)edx << 32) | eax) & XCNTXT_MASK;
BUG_ON(!valid_xcr0(feature_mask));
@@ -658,8 +651,19 @@ void xstate_init(struct cpuinfo_x86 *c)
* Set CR4_OSXSAVE and run "cpuid" to get xsave_cntxt_size.
*/
set_in_cr4(X86_CR4_OSXSAVE);
/*
* Zap the cached values to make set_xcr0() and set_msr_xss() really write
* the hardware register.
*/
this_cpu(xcr0) = 0;
if ( !set_xcr0(feature_mask) )
BUG();
if ( cpu_has_xsaves )
{
this_cpu(xss) = ~0;
set_msr_xss(0);
}
if ( bsp )
{
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.