Return-path: Received: from localhost ([127.0.0.1] helo=nanos.tec.linutronix.de) by Galois.linutronix.de with esmtp (Exim 4.80) (envelope-from ) id 1fIwzk-00063N-6s for speck@linutronix.de; Wed, 16 May 2018 16:01:32 +0200 Message-Id: <20180516135132.687640705@linutronix.de> Date: Wed, 16 May 2018 15:51:32 +0200 From: Thomas Gleixner Subject: [patch 00/15] SSB updates V17 0 Mime-Version: 1 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit To: speck@linutronix.de List-ID: This is an update to the previous 'SSB updates V16' series which addresses various review comments. Delta patch below. Git bundle comes in follow up mail. Thanks, tglx 8<----------------- diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index ae42e30e7b41..e15c27f5540c 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -140,8 +140,8 @@ static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = void x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest) { - u64 hostssbd = ssbd_tif_to_spec_ctrl(current_thread_info()->flags); - u64 msr, guest, host = x86_spec_ctrl_base; + u64 msrval, guestval, hostval = x86_spec_ctrl_base; + struct thread_info *ti = current_thread_info(); /* Is MSR_SPEC_CTRL implemented ? */ if (static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) { @@ -150,39 +150,45 @@ x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest) * modifiable bits in the host base value and or the * modifiable bits from the guest value. */ - guest = host & ~x86_spec_ctrl_mask; - guest |= guest_spec_ctrl & x86_spec_ctrl_mask; + guestval = hostval & ~x86_spec_ctrl_mask; + guestval |= guest_spec_ctrl & x86_spec_ctrl_mask; /* SSBD controlled in MSR_SPEC_CTRL */ if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD)) - host |= hostssbd; + hostval |= ssbd_tif_to_spec_ctrl(ti->flags); - if (host != guest) { - msr = setguest ? guest : host; - wrmsrl(MSR_IA32_SPEC_CTRL, msr); + if (hostval != guest_spec_ctrl) { + msrval = setguest ? guest_spec_ctrl : hostval; + wrmsrl(MSR_IA32_SPEC_CTRL, msrval); } } /* - * If SSBD is not handled in MSR_SPEC_CTRL on AMD update + * If SSBD is not handled in MSR_SPEC_CTRL on AMD, update * MSR_AMD64_L2_CFG or MSR_VIRT_SPEC_CTRL if supported. */ if (!static_cpu_has(X86_FEATURE_LS_CFG_SSBD) && !static_cpu_has(X86_FEATURE_VIRT_SSBD)) return; - /* If host has SSBD disabled via command line, force it */ + /* + * If the host has SSBD mitigation enabled, force it in the host's + * virtual MSR value. If its not permanently enabled, evaluate + * current's TIF_SSBD thread flag. + */ if (static_cpu_has(X86_FEATURE_SPEC_STORE_BYPASS_DISABLE)) - hostssbd |= SPEC_CTRL_SSBD; + hostsval = SPEC_CTRL_SSBD; + else + hostval = ssbd_tif_to_spec_ctrl(ti->flags); /* Sanitize the guest value */ - guest = guest_virt_spec_ctrl & SPEC_CTRL_SSBD; + guestval = guest_virt_spec_ctrl & SPEC_CTRL_SSBD; - if (hostssbd != guest) { + if (hostval != guestval) { unsigned long tif; - tif = setguest ? ssbd_spec_ctrl_to_tif(guest) : - ssbd_spec_ctrl_to_tif(hostssbd); + tif = setguest ? ssbd_spec_ctrl_to_tif(guestval) : + ssbd_spec_ctrl_to_tif(hostval); speculative_store_bypass_update(tif); } diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index dd37244c587a..577e7f7ae273 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -191,6 +191,7 @@ static void early_init_intel(struct cpuinfo_x86 *c) setup_clear_cpu_cap(X86_FEATURE_MSR_SPEC_CTRL); setup_clear_cpu_cap(X86_FEATURE_INTEL_STIBP); setup_clear_cpu_cap(X86_FEATURE_SSBD); + setup_clear_cpu_cap(X86_FEATURE_SPEC_CTRL_SSBD); } /* diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 80ef41a2097f..30ca2d1a9231 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -299,12 +299,20 @@ void speculative_store_bypass_ht_init(void) unsigned int cpu; st->local_state = 0; + + /* + * Shared state setup happens once on the first bringup + * of the CPU. It's not destroyed on CPU hotunplug. + */ if (st->shared_state) return; raw_spin_lock_init(&st->lock); - /* Go over HT siblings: */ + /* + * Go over HT siblings and check whether one of them has set up the + * shared state pointer already. + */ for_each_cpu(cpu, topology_sibling_cpumask(this_cpu)) { if (cpu == this_cpu) continue; @@ -316,13 +324,22 @@ void speculative_store_bypass_ht_init(void) st->shared_state = per_cpu(ssb_state, cpu).shared_state; return; } - /* Link shared state of the first HT sibling to itself. */ + + /* + * First HT sibling to come up on the core. Link shared state of + * the first HT sibling to itself. The siblings on the same core + * which come up later will see the shared state pointer and link + * themself to the state of this CPU. + */ st->shared_state = st; } /* - * Logic is: first HT sibling enables SSBD for both siblings in the core and - * last sibling to disable it, disables it for the whole core. + * Logic is: First HT sibling enables SSBD for both siblings in the core + * and last sibling to disable it, disables it for the whole core. This how + * MSR_SPEC_CTRL works in "hardware": + * + * CORE_SPEC_CTRL = THREAD0_SPEC_CTRL | THREAD1_SPEC_CTRL */ static __always_inline void amd_set_core_ssb_state(unsigned long tifn) { diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index c23d2bb0a8bf..47b1c94e035b 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -214,9 +214,9 @@ struct vcpu_svm { u64 spec_ctrl; /* - * Contains guest-controlled bits of VIRT_SPEC_CTRL, which - * will be translated into the appropriate bits to perform - * speculative control. + * Contains guest-controlled bits of VIRT_SPEC_CTRL, which will be + * translated into the appropriate L2_CFG bits on the host to + * perform speculative control. */ u64 virt_spec_ctrl;