From patchwork Fri Oct 20 11:37:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: tip-bot2 for Thomas Gleixner X-Patchwork-Id: 156045 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2010:b0:403:3b70:6f57 with SMTP id fe16csp991348vqb; Fri, 20 Oct 2023 04:39:57 -0700 (PDT) X-Google-Smtp-Source: AGHT+IH88Anzoc3mh1mO/0ILZr2PbcSlcQEI1/goB95bxpXdDJtosu0FlpFECLd2nRTZTErRWHXx X-Received: by 2002:a17:903:184:b0:1c9:fccb:3b1 with SMTP id z4-20020a170903018400b001c9fccb03b1mr7024018plg.24.1697801997209; Fri, 20 Oct 2023 04:39:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1697801997; cv=none; d=google.com; s=arc-20160816; b=FSdAHCRGMyboH1Sbs9UHbAFa+jQFJt4z7xqexDsYIGLGpGu0GKij2mWcQhZEU1Crh1 q9FpMlTRNbEr+9KuKWp5w4sGdFuqYCLGR3Ihr9mLcqEkoijWDP2PQEsaboSehYe5X1KQ bpgfTc5iKTSoIlxVsdjKqBahRPnw+t6j8ZBCuRx2zOzkT8cA31H11pWLL9k5LIj5DjYu xktDwjAAT8KyYzHVvy6MYAMoE9pbNYdoegoqntlpAZu5rzSGTUL/QM+ha7GgNPL2edwz 3uOdvkYVnYv3w4G+M+8d8MDfYJXM3Q6csN9KaTvSbi0ghaMcy0W31oN/T48sf8UfPdSz Uqtg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:references:in-reply-to:cc:subject :to:reply-to:sender:from:dkim-signature:dkim-signature:date; bh=RbbVmtC97Gh59IigR5LX8rqgp4ho0CEL+8wIxUbPnvc=; fh=LWlv3U+xZ3+vQt4tlJRIlKl5VzN7iFjjE/bzRmlxKDA=; b=giNlIJEEfyvdC0UL62L9lnYzed2/tWomDx5BSaX28xw+5KP1fDoDRkga5epVtKCzOA +LcwpN0459uKGok5EJ/fjtMUW6EZOsB9FHdg5aMRVNx8naYeDQ4EhcQXU4ajW20f8AMw WGELdJnMCdnnho58Dlh4P90+Jdgf9DI1yfQqkMw7Ga01XFSJLvdMZ3rMOlKdGmOOJT/w 3Q7iPImKsKsoFqjYLEK9pwqr/aYfMO/fIWdzeQtJ88I/OK5+yvRwXGkyYUoaWxa2qfDU +fqdJgq/+WObOlIXN43GLEaqVUKkqZO3CspZsckwwBoZLf2jKxZta8rqVzUtzRDEnRCv VMnA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=2MFAWLqT; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:5 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: from groat.vger.email (groat.vger.email. [2620:137:e000::3:5]) by mx.google.com with ESMTPS id v10-20020a170902b7ca00b001b87bd2f7b0si1475735plz.402.2023.10.20.04.39.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 04:39:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:5 as permitted sender) client-ip=2620:137:e000::3:5; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=2MFAWLqT; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:5 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by groat.vger.email (Postfix) with ESMTP id 23D098301491; Fri, 20 Oct 2023 04:39:51 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377345AbjJTLj3 (ORCPT + 25 others); Fri, 20 Oct 2023 07:39:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55440 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377324AbjJTLit (ORCPT ); Fri, 20 Oct 2023 07:38:49 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F5A81FCF; Fri, 20 Oct 2023 04:38:05 -0700 (PDT) Date: Fri, 20 Oct 2023 11:37:49 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1697801869; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RbbVmtC97Gh59IigR5LX8rqgp4ho0CEL+8wIxUbPnvc=; b=2MFAWLqTDZo5/K0hjoa6l8vYn5V4lQuKKXfL5TLSLo2CTvnRTI3QIPUicfFn5EvAXgT2kp oU7oT/DeqHZVLanZe6m0F34C1Lq5K05fuay/ZdvPVUEljB6CSCvBHpcm2nUVQ7Ipe8nDsO SeOTFT10mMI/yTVgjKGBh4I5Lm0hQ1spINHpqwVQQpbtHqsWeZ31rDDAWEPb0/PxYW/2fH kUpK1zntOEH9uxuHDWZQwadNHdB1jMgmDZpyU00988meq9Jn4OwZmFAcgPC1UqG/+lu0Df wQXwGoeu//iEoaSqkI2RvUCV7jeAMvb9TdGIELoZzE1m1MStk8PeS+mJL4TsLg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1697801869; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RbbVmtC97Gh59IigR5LX8rqgp4ho0CEL+8wIxUbPnvc=; b=1ow8fSGqfW13V+Z241pi1AkiEANayKfjNuNoJnvk5A8X4fmUwP+cdBko41wPF8PaFTTnNi wMHZ/J5GYg56R8Cw== From: "tip-bot2 for Thomas Gleixner" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/microcode] x86/microcode: Provide new control functions Cc: Thomas Gleixner , "Borislav Petkov (AMD)" , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20231002115903.377922731@linutronix.de> References: <20231002115903.377922731@linutronix.de> MIME-Version: 1.0 Message-ID: <169780186923.3135.11355710871406104676.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on groat.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (groat.vger.email [0.0.0.0]); Fri, 20 Oct 2023 04:39:51 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1778649797995562767 X-GMAIL-MSGID: 1780274427084069970 The following commit has been merged into the x86/microcode branch of tip: Commit-ID: 1844a781fdfbcbff64bfa59bd71fc6a62fdcdac0 Gitweb: https://git.kernel.org/tip/1844a781fdfbcbff64bfa59bd71fc6a62fdcdac0 Author: Thomas Gleixner AuthorDate: Mon, 02 Oct 2023 14:00:02 +02:00 Committer: Borislav Petkov (AMD) CommitterDate: Thu, 19 Oct 2023 15:58:39 +02:00 x86/microcode: Provide new control functions The current all in one code is unreadable and really not suited for adding future features like uniform loading with package or system scope. Provide a set of new control functions which split the handling of the primary and secondary CPUs. These will replace the current rendezvous all in one function in the next step. This is intentionally a separate change because diff makes an complete unreadable mess otherwise. So the flow separates the primary and the secondary CPUs into their own functions which use the control field in the per CPU ucode_ctrl struct. primary() secondary() wait_for_all() wait_for_all() apply_ucode() wait_for_release() release() apply_ucode() Signed-off-by: Thomas Gleixner Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20231002115903.377922731@linutronix.de --- arch/x86/kernel/cpu/microcode/core.c | 84 +++++++++++++++++++++++++++- 1 file changed, 84 insertions(+) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 001c004..1ff38f9 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -290,6 +290,90 @@ static bool wait_for_cpus(atomic_t *cnt) return false; } +static bool wait_for_ctrl(void) +{ + unsigned int timeout; + + for (timeout = 0; timeout < USEC_PER_SEC; timeout++) { + if (this_cpu_read(ucode_ctrl.ctrl) != SCTRL_WAIT) + return true; + udelay(1); + if (!(timeout % 1000)) + touch_nmi_watchdog(); + } + return false; +} + +static __maybe_unused void load_secondary(unsigned int cpu) +{ + unsigned int ctrl_cpu = this_cpu_read(ucode_ctrl.ctrl_cpu); + enum ucode_state ret; + + /* Initial rendezvous to ensure that all CPUs have arrived */ + if (!wait_for_cpus(&late_cpus_in)) { + pr_err_once("load: %d CPUs timed out\n", atomic_read(&late_cpus_in) - 1); + this_cpu_write(ucode_ctrl.result, UCODE_TIMEOUT); + return; + } + + /* + * Wait for primary threads to complete. If one of them hangs due + * to the update, there is no way out. This is non-recoverable + * because the CPU might hold locks or resources and confuse the + * scheduler, watchdogs etc. There is no way to safely evacuate the + * machine. + */ + if (!wait_for_ctrl()) + panic("Microcode load: Primary CPU %d timed out\n", ctrl_cpu); + + /* + * If the primary succeeded then invoke the apply() callback, + * otherwise copy the state from the primary thread. + */ + if (this_cpu_read(ucode_ctrl.ctrl) == SCTRL_APPLY) + ret = microcode_ops->apply_microcode(cpu); + else + ret = per_cpu(ucode_ctrl.result, ctrl_cpu); + + this_cpu_write(ucode_ctrl.result, ret); + this_cpu_write(ucode_ctrl.ctrl, SCTRL_DONE); +} + +static __maybe_unused void load_primary(unsigned int cpu) +{ + struct cpumask *secondaries = topology_sibling_cpumask(cpu); + enum sibling_ctrl ctrl; + enum ucode_state ret; + unsigned int sibling; + + /* Initial rendezvous to ensure that all CPUs have arrived */ + if (!wait_for_cpus(&late_cpus_in)) { + this_cpu_write(ucode_ctrl.result, UCODE_TIMEOUT); + pr_err_once("load: %d CPUs timed out\n", atomic_read(&late_cpus_in) - 1); + return; + } + + ret = microcode_ops->apply_microcode(cpu); + this_cpu_write(ucode_ctrl.result, ret); + this_cpu_write(ucode_ctrl.ctrl, SCTRL_DONE); + + /* + * If the update was successful, let the siblings run the apply() + * callback. If not, tell them it's done. This also covers the + * case where the CPU has uniform loading at package or system + * scope implemented but does not advertise it. + */ + if (ret == UCODE_UPDATED || ret == UCODE_OK) + ctrl = SCTRL_APPLY; + else + ctrl = SCTRL_DONE; + + for_each_cpu(sibling, secondaries) { + if (sibling != cpu) + per_cpu(ucode_ctrl.ctrl, sibling) = ctrl; + } +} + static int load_cpus_stopped(void *unused) { int cpu = smp_processor_id();