x86/amd: don't set X86_BUG_SYSRET_SS_ATTRS when running under Xen
authorJuergen Gross <jgross@suse.com>
Thu, 27 Apr 2017 05:01:20 +0000 (07:01 +0200)
committerJuergen Gross <jgross@suse.com>
Thu, 11 May 2017 13:55:14 +0000 (15:55 +0200)
When running as Xen pv guest X86_BUG_SYSRET_SS_ATTRS must not be set
on AMD cpus.

This bug/feature bit is kind of special as it will be used very early
when switching threads. Setting the bit and clearing it a little bit
later leaves a critical window where things can go wrong. This time
window has enlarged a little bit by using setup_clear_cpu_cap() instead
of the hypervisor's set_cpu_features callback. It seems this larger
window now makes it rather easy to hit the problem.

The proper solution is to never set the bit in case of Xen.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Juergen Gross <jgross@suse.com>
arch/x86/kernel/cpu/amd.c
arch/x86/xen/enlighten_pv.c

index c36140d788fe215aadb3a8f27a8de040f2c44c06..b6da6e75e3a83f024460dcd4b10060a67d85d8ad 100644 (file)
@@ -799,8 +799,9 @@ static void init_amd(struct cpuinfo_x86 *c)
                if (cpu_has(c, X86_FEATURE_3DNOW) || cpu_has(c, X86_FEATURE_LM))
                        set_cpu_cap(c, X86_FEATURE_3DNOWPREFETCH);
 
-       /* AMD CPUs don't reset SS attributes on SYSRET */
-       set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
+       /* AMD CPUs don't reset SS attributes on SYSRET, Xen does. */
+       if (!cpu_has(c, X86_FEATURE_XENPV))
+               set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
 }
 
 #ifdef CONFIG_X86_32
index b5c54ab0e195733f837882de09e61aea0fe3649d..7cd442690f9dd6dc7af94d35f883becea31768bb 100644 (file)
@@ -290,7 +290,6 @@ static bool __init xen_check_xsave(void)
 
 static void __init xen_init_capabilities(void)
 {
-       setup_clear_cpu_cap(X86_BUG_SYSRET_SS_ATTRS);
        setup_force_cpu_cap(X86_FEATURE_XENPV);
        setup_clear_cpu_cap(X86_FEATURE_DCA);
        setup_clear_cpu_cap(X86_FEATURE_APERFMPERF);