| From 35b8de6f6b9abfe9dfb44308e58cbf5461e9ceba Mon Sep 17 00:00:00 2001 |
| From: David Woodhouse <dwmw@amazon.co.uk> |
| Date: Sun, 20 May 2018 20:51:10 +0100 |
| Subject: x86/amd: don't set X86_BUG_SYSRET_SS_ATTRS when running under Xen |
| |
| commit def9331a12977770cc6132d79f8e6565871e8e38 upstream |
| |
| 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> |
| Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/kernel/cpu/amd.c | 5 +++-- |
| arch/x86/xen/enlighten.c | 4 +--- |
| 2 files changed, 4 insertions(+), 5 deletions(-) |
| |
| --- a/arch/x86/kernel/cpu/amd.c |
| +++ b/arch/x86/kernel/cpu/amd.c |
| @@ -824,8 +824,9 @@ static void init_amd(struct cpuinfo_x86 |
| 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 |
| --- a/arch/x86/xen/enlighten.c |
| +++ b/arch/x86/xen/enlighten.c |
| @@ -1977,10 +1977,8 @@ EXPORT_SYMBOL_GPL(xen_hvm_need_lapic); |
| |
| static void xen_set_cpu_features(struct cpuinfo_x86 *c) |
| { |
| - if (xen_pv_domain()) { |
| - clear_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); |
| + if (xen_pv_domain()) |
| set_cpu_cap(c, X86_FEATURE_XENPV); |
| - } |
| } |
| |
| static void xen_pin_vcpu(int cpu) |