From patchwork Tue Sep 12 07:58:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 138014 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9ecd:0:b0:3f2:4152:657d with SMTP id t13csp250479vqx; Tue, 12 Sep 2023 01:10:31 -0700 (PDT) X-Google-Smtp-Source: AGHT+IETk0Yfu+56wX61LUeBqFM/Xqal00CqUxETNBGACF6Ggu1hu7UwbVqSv2UuAWenMxFp7AdM X-Received: by 2002:a05:6870:e38b:b0:1c8:39a6:77a9 with SMTP id x11-20020a056870e38b00b001c839a677a9mr11791618oad.31.1694506231721; Tue, 12 Sep 2023 01:10:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694506231; cv=none; d=google.com; s=arc-20160816; b=anPN+shCGfFCVdCjMaJUL5DupWOLgWvEUs17N6qImWhi3K879lLZq8j/g/hYqqev6f SAiswQCGV5wmbDduh2F6LNcRJs7UKFFnIwxPeKgAp4KXlIF/e5KnkPXUOQVKhATXKZtU HxlR04i10XjggadTnd9a693rFZXqf0c+jz3p7qYQriKbxhHAyjRBwa7FLV0LZ1ltLfRK F5u3uDKp+MlPacECRegiA1IfI+XNI4/PzkLYHJKXAFTFbnSrDVZyKsKn4oax5LmjFRCN 8Hvyxs44sOsmDEt+p38pdYEYs117xGfxSuIU+WJUtZSquihDiITj52qtfPNUo9Ev1wCw uHrQ== 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=tcStbJBYGm1S6mX3lupmzFXgqW4kHxxe4AHt7jQaeKc=; fh=u57tXYamzTrJA+Ht8n1u7SfTMptrQaIb6LVW+jsaYf4=; b=x6pv7eS+HC0rGeoui5DCgfUCH2215RJiXy7cxo6PAcmumF9YT8nsdhHdi8uDPR+Lb6 layhqspjWTEi1v/ZxpWcQsXxR9lTMBOHN5MqjeqC8kB7T3QfkNTZH+PrgPH4BG9EqnBQ iR7AhsHuX87o7Aco96f/iiXUIeOZd4sCVAhv/LgCglAN9mOf/B3lJYjxmLjbkLuwBIsU Y2h9y+qGwBYWPNp9bgBKuM8YTsPCXyBybWdU/6wdIhmA4zxIWCZDkk2fGlMrlbjzy5Ug 1ted9fIsp+yXKOg/H02GuaBfwKW9qdCJ2gfAqIr6KMpkp0hY1RmFs+MmKI3jTfEAT272 3VFw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=TxPEeNSA; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e; 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 u69-20020a638548000000b00565efb7b3efsi4943569pgd.225.2023.09.12.01.10.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 01:10:31 -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=TxPEeNSA; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e; 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 41BE78029896; Tue, 12 Sep 2023 01:01:21 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.8 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232062AbjILIAe (ORCPT + 39 others); Tue, 12 Sep 2023 04:00:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232169AbjILH7N (ORCPT ); Tue, 12 Sep 2023 03:59:13 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F259926AC for ; Tue, 12 Sep 2023 00:58:21 -0700 (PDT) Message-ID: <20230912065502.202675936@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1694505500; 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=tcStbJBYGm1S6mX3lupmzFXgqW4kHxxe4AHt7jQaeKc=; b=TxPEeNSADqF/1espoa4joMFPyaHU6sd/ZlOPhCdIrC7wCV7KkIwcL/CpJ3otO5/BeCCDCo eQM3VPvorqp+UHwR7xfGfR7oqCQMrU6H2AcGCDyFDt8NSD/2zPH3lA7Gbjqn4jFKln0mKf SvzyPyAAw/gjlJuf9mzIRFtSt5z/x0/+/YbOY7SGuSJDaiOaIpxabQPr/ONgil6EmnyV3y sMju8Gu3jM0lADivxRf8YWsQG72GcHPQNwgKPfHr4QMWpvfHJL/RVnxECXZ7eadRM0V1JL YnXR2WMROfkL7M/aK2fvIj7V2oMjuGhCn0C3CVYbwmp0C8NGIvdJYreJzxl/0A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1694505500; 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=tcStbJBYGm1S6mX3lupmzFXgqW4kHxxe4AHt7jQaeKc=; b=cAq/Q/RnWWyE8qyo5fCPHQbCSaX+Da2dUskr+Di+xg/82NEnYLBZSh4+X9yo3WN+YSDnT7 fO+si2bL29tUcAAw== From: Thomas Gleixner To: LKML Cc: x86@kernel.org, Borislav Petkov , "Chang S. Bae" , Arjan van de Ven , Nikolay Borisov Subject: [patch V3 23/30] x86/microcode: Provide new control functions References: <20230912065249.695681286@linutronix.de> MIME-Version: 1.0 Date: Tue, 12 Sep 2023 09:58:20 +0200 (CEST) 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]); Tue, 12 Sep 2023 01:01:21 -0700 (PDT) X-Spam-Status: No, score=-0.9 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 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1776818566037316163 X-GMAIL-MSGID: 1776818566037316163 From: Thomas Gleixner 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 rendevouz 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 --- arch/x86/kernel/cpu/microcode/core.c | 86 +++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) --- --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -357,6 +357,92 @@ 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 ucode_load_secondary(unsigned int cpu) +{ + unsigned int ctrl_cpu = this_cpu_read(ucode_ctrl.ctrl_cpu); + enum ucode_state ret; + + /* Initial rendevouz to ensure that all CPUs have arrived */ + if (!wait_for_cpus(&late_cpus_in)) { + pr_err_once("Microcode 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 ucode_load_primary(unsigned int cpu) +{ + struct cpumask *secondaries = topology_sibling_cpumask(cpu); + enum sibling_ctrl ctrl; + enum ucode_state ret; + unsigned int sibling; + + /* Initial rendevouz 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("Microcode 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 ucode_load_cpus_stopped(void *unused) { int cpu = smp_processor_id();