summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '0033-x86-xstate-Fix-initialisation-of-XSS-cache.patch')
-rw-r--r--0033-x86-xstate-Fix-initialisation-of-XSS-cache.patch74
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
+