Message ID | 20211103184020.1276465-1-marmarek@invisiblethingslab.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [PATCH-4.16,v2] x86/xstate: reset cached register values on resume | expand |
Marek Marczykowski-Górecki writes ("[PATCH-4.16 v2] x86/xstate: reset cached register values on resume"): > set_xcr0() and set_msr_xss() use cached value to avoid setting the > register to the same value over and over. But suspend/resume implicitly > reset the registers and since percpu areas are not deallocated on > suspend anymore, the cache gets stale. > Reset the cache on resume, to ensure the next write will really hit the > hardware. Choose value 0, as it will never be a legitimate write to > those registers - and so, will force write (and cache update). > > Note the cache is used io get_xcr0() and get_msr_xss() too, but: > - set_xcr0() is called few lines below in xstate_init(), so it will > update the cache with appropriate value > - get_msr_xss() is not used anywhere - and thus not before any > set_msr_xss() that will fill the cache > > Fixes: aca2a985a55a "xen: don't free percpu areas during suspend" > Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> > Reviewed-by: Jan Beulich <jbeulich@suse.com> > --- > Changes in v2: > - adjust xss init value per Jan request > > For 4.16: this unbreaks S3 resume, it was posted initially back in > August and is shipped in Qubes since September (although backported to > 4.14, not unstable) with no reported regressions. Thank you. I went back and read the thread. Thanks to everyone who contributed there. Release-Acked-by: Ian Jackson <iwj@xenproject.org>
diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c index 6aaf9a2f1546..a16dfbb3877b 100644 --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -642,6 +642,13 @@ void xstate_init(struct cpuinfo_x86 *c) return; } + /* + * Clear the cached value 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));