Received: by 2002:a05:7412:6592:b0:d7:7d3a:4fe2 with SMTP id m18csp580898rdg; Thu, 10 Aug 2023 12:07:47 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE5laYo4lDHGg6eiiYG9Jg/6cPBySKfgpLR4dXOwXMoVXjGZ7u6HD01FgnWNbzdJ+88BCf/ X-Received: by 2002:a05:6a20:8f03:b0:137:57fc:4f9d with SMTP id b3-20020a056a208f0300b0013757fc4f9dmr4178597pzk.10.1691694466683; Thu, 10 Aug 2023 12:07:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691694466; cv=none; d=google.com; s=arc-20160816; b=VeUGDCywmIN6WNrUZYxDMeCLh5O7adygCPkoN9yDGxGbg+bEGsyjasrDmkfsDvqmbX IbcUg33uWhS5iqRBv9tQNjs6ill8CGoAgYyuKgN2viIpbakUpp8o8Gl+lGWBWbaSh6pr Qs6H0wn4DpQGtibPl7y/0cm1DC1bC22wsG33RKhdCT048YT5TVnIvRp3HvE0HiJtXRlo qrrsQUCJh2DB7Jqzli8LAAOBYWhKxA2hQIcElsQvgB78DIGXjAzFhP3UBEmt1jqLNIi2 5dy3bBPtcLXigAIrFXbG5qIGvZ74F9mGkEvL5mzxl3pAA4KsV1BD0CpleD70glmibDpt GNjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:date:mime-version:references:subject:cc:to:from :dkim-signature:dkim-signature:message-id; bh=KXmWi+498NlTG+8QbtY9G0BWF4sNUEz4Qvdk7zq0Ox4=; fh=Vp72a/EEov1VOHpGPkCjAnDQEmhhYrQPa+PSfT8H2jQ=; b=BqCi2IVLJwd7vWpREsSy4/mDoGL4CVBFO6MIJESWvP/LFN670SczvNYCMQ864Mfi6H ZoXe9rV9ZLMByVYysGjwqf/SQ+7NcmaciUSw1j+gZPD83VpEtWWFJ7N7qxS3E5ZzkfLU 0l3FEs+Bn4wSZhwTKAyErnwNZLarkatXjkqIo05+PMmsBIkwKaEK5sCuJS+7wE9kES/s 30hd0UuQQaHmA30DzdIistc6/6asAut5r+snFme/PttuNwv89NETXKi10iy3V05OGfev eadr2b5OignD7saG2mnfvhEhJ3vCBGvPMKvJWaZ/a0nUSZpt2aHvFo99nafn9Hi7Abpv W7Bg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=2yfFPqVq; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=MYXcUVgo; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id t2-20020a639542000000b005652bd27e77si2111139pgn.828.2023.08.10.12.07.30; Thu, 10 Aug 2023 12:07:46 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=2yfFPqVq; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=MYXcUVgo; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235718AbjHJSjh (ORCPT + 99 others); Thu, 10 Aug 2023 14:39:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57776 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235958AbjHJSjM (ORCPT ); Thu, 10 Aug 2023 14:39:12 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D9F2D3AB7 for ; Thu, 10 Aug 2023 11:38:35 -0700 (PDT) Message-ID: <20230810160806.506010083@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1691692686; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=KXmWi+498NlTG+8QbtY9G0BWF4sNUEz4Qvdk7zq0Ox4=; b=2yfFPqVqwC1UiB2xLp4JD4uI//CEWRSXljATSIrPMMRU9OCUMS3NKxgEnWpp+sNqTy7BYN WN35mdONac/s+MlFJGRw34qku9KLT58+vfjJ9ul9OwWrx5UpOGLKGyfkXb8xkPQyJaCNkD GfcKWv4DIpaLlD/CWcJKtvdHssdU2yJvFF+tMYmXEDeOWmGhSzySpKKK93XLdioBUzCNJ/ JwiEp6HQ3KsI5iV1ek5McY5nUMHJP76z6aYBAJ/4Rarsj6w91nbS3kRzi6A3O8wjCzDw2U j9m3FUpcE4qCaCywul71XanbvrNIuNZWcSTS+kTfRQQo+1/j9zpPCiUDPg3liw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1691692686; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=KXmWi+498NlTG+8QbtY9G0BWF4sNUEz4Qvdk7zq0Ox4=; b=MYXcUVgor8U2LoMdsSSnv3y9xcLW/xFpVjjRNP88uPjFXxta9KQ6qcWlaWn6e08c32ZVJx zO3m/y0HiW5DwmCw== From: Thomas Gleixner To: LKML Cc: x86@kernel.org, Borislav Petkov , Ashok Raj , Arjan van de Ven Subject: [patch 27/30] x86/apic: Provide apic_force_nmi_on_cpu() References: <20230810153317.850017756@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Date: Thu, 10 Aug 2023 20:38:06 +0200 (CEST) X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Thomas Gleixner When SMT siblings are soft-offlined and parked in one of the play_dead() variants they still react on NMI, which is problematic on affected Intel CPUs. The default play_dead() variant uses MWAIT on modern CPUs, which is not guaranteed to be safe when updated concurrently. Right now late loading is prevented when not all SMT siblings are online, but as they still react on NMI, it is possible to bring them out of their park position into a trivial rendevouz handler. Provide a function which allows to do that. I does sanity checks whether the target is in the cpus_booted_once_mask and whether the APIC driver supports it. Mark X2APIC and XAPIC as capable, but exclude 32bit and the UV and NUMACHIP variants as that needs feedback from the relevant experts. Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/apic.h | 5 +++++ arch/x86/kernel/apic/apic_flat_64.c | 2 ++ arch/x86/kernel/apic/ipi.c | 9 ++++++++- arch/x86/kernel/apic/x2apic_cluster.c | 1 + arch/x86/kernel/apic/x2apic_phys.c | 1 + 5 files changed, 17 insertions(+), 1 deletion(-) --- diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 98c32aa5963a..e219e6c62138 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -301,6 +301,9 @@ struct apic { enum apic_delivery_modes delivery_mode; bool dest_mode_logical; + /* Allows to send an NMI to an "offline" CPU which hangs in *play_dead() */ + bool nmi_to_offline_cpu; + u32 (*calc_dest_apicid)(unsigned int cpu); /* ICR related functions */ @@ -505,6 +508,8 @@ extern void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *r extern int default_cpu_present_to_apicid(int mps_cpu); extern int default_check_phys_apicid_present(int phys_apicid); +void apic_send_nmi_to_offline_cpu(unsigned int cpu); + #endif /* CONFIG_X86_LOCAL_APIC */ #ifdef CONFIG_SMP diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 8f72b4351c9f..4340f471e6a6 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -138,6 +138,7 @@ static struct apic apic_flat __ro_after_init = { .send_IPI_allbutself = default_send_IPI_allbutself, .send_IPI_all = default_send_IPI_all, .send_IPI_self = default_send_IPI_self, + .nmi_to_offline_cpu = true, .inquire_remote_apic = default_inquire_remote_apic, @@ -229,6 +230,7 @@ static struct apic apic_physflat __ro_after_init = { .send_IPI_allbutself = default_send_IPI_allbutself, .send_IPI_all = default_send_IPI_all, .send_IPI_self = default_send_IPI_self, + .nmi_to_offline_cpu = true, .inquire_remote_apic = default_inquire_remote_apic, diff --git a/arch/x86/kernel/apic/ipi.c b/arch/x86/kernel/apic/ipi.c index 2a6509e8c840..6ee6cce4423a 100644 --- a/arch/x86/kernel/apic/ipi.c +++ b/arch/x86/kernel/apic/ipi.c @@ -95,8 +95,15 @@ void native_send_call_func_ipi(const struct cpumask *mask) apic->send_IPI_mask(mask, CALL_FUNCTION_VECTOR); } +void apic_send_nmi_to_offline_cpu(unsigned int cpu) +{ + if (WARN_ON_ONCE(!apic->nmi_to_offline_cpu)) + return; + if (WARN_ON_ONCE(!cpumask_test_cpu(cpu, &cpus_booted_once_mask))) + return; + apic->send_IPI(cpu, NMI_VECTOR); +} #endif /* CONFIG_SMP */ - static inline int __prepare_ICR2(unsigned int mask) { return SET_XAPIC_DEST_FIELD(mask); diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index b2b2b7f3e03f..685437a98463 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -264,6 +264,7 @@ static struct apic apic_x2apic_cluster __ro_after_init = { .send_IPI_allbutself = x2apic_send_IPI_allbutself, .send_IPI_all = x2apic_send_IPI_all, .send_IPI_self = x2apic_send_IPI_self, + .nmi_to_offline_cpu = true, .inquire_remote_apic = NULL, diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index 896bc41cb2ba..d5e44cb7e15f 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -188,6 +188,7 @@ static struct apic apic_x2apic_phys __ro_after_init = { .send_IPI_allbutself = x2apic_send_IPI_allbutself, .send_IPI_all = x2apic_send_IPI_all, .send_IPI_self = x2apic_send_IPI_self, + .nmi_to_offline_cpu = true, .inquire_remote_apic = NULL,