diff options
Diffstat (limited to '0033-x86-xstate-Fix-initialisation-of-XSS-cache.patch')
-rw-r--r-- | 0033-x86-xstate-Fix-initialisation-of-XSS-cache.patch | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/0033-x86-xstate-Fix-initialisation-of-XSS-cache.patch b/0033-x86-xstate-Fix-initialisation-of-XSS-cache.patch new file mode 100644 index 0000000..1a8c724 --- /dev/null +++ b/0033-x86-xstate-Fix-initialisation-of-XSS-cache.patch @@ -0,0 +1,74 @@ +From 4ee1df89d9c92609e5fff3c9b261ce4b1bb88e42 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Wed, 26 Jun 2024 13:43:19 +0200 +Subject: [PATCH 33/56] 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: f7f4a523927f ("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: 9e6dbbe8bf400aacb99009ddffa91d2a0c312b39 +master date: 2024-06-19 13:00:06 +0100 +--- + xen/arch/x86/xstate.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c +index f442610fc5..ca76f98fe2 100644 +--- a/xen/arch/x86/xstate.c ++++ b/xen/arch/x86/xstate.c +@@ -641,13 +641,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)); +@@ -657,8 +650,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 ) + { +-- +2.45.2 + |