Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp2639179imm; Tue, 4 Sep 2018 07:45:02 -0700 (PDT) X-Google-Smtp-Source: ANB0Vdb9L4x/Gl9uoARul3ryBtXoPO9XilGZUYvamUipz45jR7BJlvdPpCvU44JA/Tv2p/9d+5Mz X-Received: by 2002:a63:d613:: with SMTP id q19-v6mr31805185pgg.327.1536072301901; Tue, 04 Sep 2018 07:45:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536072301; cv=none; d=google.com; s=arc-20160816; b=FOUaayS84yQErk6L9SjID7OAtahk1D2/sJxqz3+uiyeiUvRKUa35Yjwp0jw/cCWDwC HJMQkLAm50DXmBxTJsimccWGckQ6ZKQ/4cVNQHdXiJ21ILHKO9MC39bAIcCh8Vt2jaqB AHP1jBPdof7Cs32E2TWIm5KHuIkfUe3uRK4JB8onoQYhhqqcxsp7SJV9dJh9XT0tNczg 06eCntXKRy6HoP6Cr/tB6Zax/uLnQvzMKTky3FUBPFOkLrrn8mcHhdLjxRb3ADEpiXLD 0743j+8e8fqGhKwgfgK0GAnsWwX5ZdIOjWp05UzSSM43SH+y5goMDuIAGyFHUC61m1yk 0Dmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :message-id:in-reply-to:subject:cc:to:from:date :arc-authentication-results; bh=HzmsykKc6Gx9q/oZ5aSErfehU8VoiULw2TclGyogbeA=; b=ce/QRV1V2RYYV8u/ZYRfWe3Ln1RqsMtvMTR2xepZuthKm6nGPg3chEW3T8hYvVvgaS 5+5IbjjNIPUg9YTmkjVuQnxiP1YsAtIJwjTGlnJmekRH1jG5b5iUwRVbrby4bo/35MFp nIOwPNgmMfCmA0yfZRAg/wn9j+6iEoDP1GfB4kH1Oscs05KF6QcRZyeW5jzZmHcE1NAy F7qDqXuOwVGkmSMmA2sShxGDeEHPZ9dUodHygPX1koZjTHvC4CJkXkhojK7uYzGfBp8P AxObSnk3Y+dMWG/ovj7+fZHMau6YkE1gUjaPGnfvSDKquYRg5qlkXNGhgDSjMhLPKRFV xMkQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d4-v6si21556572pla.299.2018.09.04.07.44.47; Tue, 04 Sep 2018 07:45:01 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727680AbeIDTIc (ORCPT + 99 others); Tue, 4 Sep 2018 15:08:32 -0400 Received: from twin.jikos.cz ([91.219.245.39]:36349 "EHLO twin.jikos.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726168AbeIDTIb (ORCPT ); Tue, 4 Sep 2018 15:08:31 -0400 Received: from twin.jikos.cz (jikos@[127.0.0.1]) by twin.jikos.cz (8.13.6/8.13.6) with ESMTP id w84Egfbk029283 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 4 Sep 2018 16:42:42 +0200 Received: from localhost (jikos@localhost) by twin.jikos.cz (8.13.6/8.13.6/Submit) with ESMTP id w84EgfeX029098; Tue, 4 Sep 2018 16:42:41 +0200 X-Authentication-Warning: twin.jikos.cz: jikos owned process doing -bs Date: Tue, 4 Sep 2018 16:42:41 +0200 (CEST) From: Jiri Kosina To: Thomas Gleixner , Ingo Molnar , Peter Zijlstra , Josh Poimboeuf , Andrea Arcangeli , "Woodhouse, David" , Oleg Nesterov , Tim Chen cc: linux-kernel@vger.kernel.org, x86@kernel.org Subject: [PATCH v3 3/3] x86/speculation: Enable cross-hyperthread spectre v2 STIBP mitigation In-Reply-To: Message-ID: References: User-Agent: Alpine 2.00 (LRH 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jiri Kosina STIBP is a feature provided by certain Intel ucodes / CPUs. This feature (once enabled) prevents cross-hyperthread control of decisions made by indirect branch predictors. Enable this feature if - the CPU is vulnerable to spectre v2 - the CPU supports SMT and has SMT siblings online - spectre_v2 mitigation autoselection is enabled (default) After some previous discussion, this patch leaves STIBP on all the time, as wrmsr on crossing kernel boundary is a no-no. This could perhaps later be a bit more optimized (like disabling it in NOHZ, experiment with disabling it in idle, etc) if needed. Note: the code could be made less awkward if it'd be guaranteed that STIBP could be kept on on a primary thread with SMT sibling being offline, without potentially imposing performance penalty. This doesn't seem to be defined anywhere though, so let's better be safe then sorry and always flip STIBP both on primary and sibling threads on hotplug transitions. Cc: stable@vger.kernel.org Signed-off-by: Jiri Kosina --- Sorry for the resend, my pine is buggered and broke threading. arch/x86/kernel/cpu/bugs.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/cpu.c | 13 +++++++++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 40bdaea97fe7..ba3df0a49a2e 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -325,6 +325,56 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) return cmd; } +static bool stibp_needed(void) +{ + if (spectre_v2_enabled == SPECTRE_V2_NONE) + return false; + + if (cpu_smt_control != CPU_SMT_ENABLED) + return false; + + if (!boot_cpu_has(X86_FEATURE_STIBP)) + return false; + + return true; +} + +/* + * The read-modify-write of the MSR doesn't need any race protection here, + * as we're running in atomic context. + */ +static void enable_stibp(void *info) +{ + u64 mask; + rdmsrl(MSR_IA32_SPEC_CTRL, mask); + mask |= SPEC_CTRL_STIBP; + wrmsrl(MSR_IA32_SPEC_CTRL, mask); +} + +static void disable_stibp(void *info) +{ + u64 mask; + rdmsrl(MSR_IA32_SPEC_CTRL, mask); + mask &= ~SPEC_CTRL_STIBP; + wrmsrl(MSR_IA32_SPEC_CTRL, mask); +} + +void arch_smt_enable_errata(void) +{ + if (stibp_needed()) { + pr_info("Spectre v2 cross-process SMT mitigation: Enabling STIBP\n"); + on_each_cpu(enable_stibp, NULL, 1); + } +} + +void arch_smt_disable_errata(void) +{ + if (stibp_needed()) { + pr_info("Spectre v2 cross-process SMT mitigation: Disabling STIBP\n"); + on_each_cpu(disable_stibp, NULL, 1); + } +} + static void __init spectre_v2_select_mitigation(void) { enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline(); @@ -424,6 +474,9 @@ static void __init spectre_v2_select_mitigation(void) setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW); pr_info("Enabling Restricted Speculation for firmware calls\n"); } + + /* Enable STIBP on BP if needed */ + arch_smt_enable_errata(); } #undef pr_fmt @@ -655,6 +708,16 @@ void x86_spec_ctrl_setup_ap(void) if (ssb_mode == SPEC_STORE_BYPASS_DISABLE) x86_amd_ssb_disable(); + + /* + * If we are here during system bootup, enable STIBP. + * + * If we are here because of SMT hotplug, STIBP will be enabled by the + * SMT control code (enabling here would not be sufficient, as it + * needs to happen on primary threads as well). + */ + if (stibp_needed() && system_state < SYSTEM_RUNNING) + enable_stibp(NULL); } #undef pr_fmt diff --git a/kernel/cpu.c b/kernel/cpu.c index aa7fe85ad62e..d3613d546829 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -2025,17 +2025,27 @@ static void cpuhp_online_cpu_device(unsigned int cpu) kobject_uevent(&dev->kobj, KOBJ_ONLINE); } +/* + * Architectures that need SMT-specific errata handling during SMT hotplug + * should override these. + */ +void __weak arch_smt_enable_errata(void) { }; +void __weak arch_smt_disable_errata(void) { }; + static int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) { int cpu, ret = 0; cpu_maps_update_begin(); + arch_smt_disable_errata(); for_each_online_cpu(cpu) { if (topology_is_primary_thread(cpu)) continue; ret = cpu_down_maps_locked(cpu, CPUHP_OFFLINE); - if (ret) + if (ret) { + arch_smt_enable_errata(); break; + } /* * As this needs to hold the cpu maps lock it's impossible * to call device_offline() because that ends up calling @@ -2073,6 +2083,7 @@ static int cpuhp_smt_enable(void) /* See comment in cpuhp_smt_disable() */ cpuhp_online_cpu_device(cpu); } + arch_smt_enable_errata(); cpu_maps_update_done(); return ret; } -- Jiri Kosina SUSE Labs