Received: by 2002:a05:7412:6592:b0:d7:7d3a:4fe2 with SMTP id m18csp1728219rdg; Sat, 12 Aug 2023 13:48:46 -0700 (PDT) X-Google-Smtp-Source: AGHT+IESo5UEg4oJEwbb7omcUC5/l3KDdjbD6jpCUtTOp6bA1ieOL2PGZ1Pz4GtRBDanJHq4CKXj X-Received: by 2002:a17:902:db03:b0:1bb:2020:be0d with SMTP id m3-20020a170902db0300b001bb2020be0dmr7503969plx.14.1691873326600; Sat, 12 Aug 2023 13:48:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691873326; cv=none; d=google.com; s=arc-20160816; b=SLRzQx+q9qB4ZLEqFiqpCL6YizD2XwXYzOD7E35uM61HARDkEDNMauaYH4hkbbWhtX Q7RC7D2ul0baQnbMp/4d4UaAEHLc272vt3cHnUXXfCdgFvacUqkQNCzX8xcah5U+0RgI zlnlGZqHu1FaxcoThkMCOmRveYA5wbH+ZR0YijJO2lWYVEuVtKWOm0fzR5O/F6Cs2VkR eCBY7jrqGUv6kamh+glXlYlnCX053e36sKomEgXMyD6lck0qu+4CcDQKrcU9FV716u/P F95rGzAvWCwkSBS9MThsoOt6hJrIhJ6LhvHe4adYqgpbyzEu2N2B2L+et4jhCiYc14Ek SG2Q== 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=yVae3u0BRTnDkPuniOcxLkA1wgvMDfOA8XxNsc4ELm4=; b=i31mXygOpgAWdUhs73KHtpEmgWnnZsk1q1RzS0uwcIPspxhZdAeOruCLltMamLQQ4x vryyGmobAWU7hqsu44EmXZ0VgB62EAcu2Sj7q4nwl95aae1CKo8gOpryizt116tmoc02 5aOkcAJ4Q6s/wnuEHkRP4sBZ5hea6xkjIgidYlj9C6gn6x+zagwRCY/OBfSGbrK1UFT9 +0GVtZ5rvcWNb2p0fUBCnzPVWljR88BVceSD7tye6n08NfVx7U/nHpxSI31XqAudJ5h5 42XIc4yWjAmPvPbZlUHrIs6xEbENIprqujcYpG+ILQ7216JbDyycAy3NxuJseXnNSxqK P8ug== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=M3fEcYwR; 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::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 b4-20020a170902d88400b001b7fa1a9a36si5202237plz.67.2023.08.12.13.48.35; Sat, 12 Aug 2023 13:48: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=M3fEcYwR; 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::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 S231277AbjHLUG5 (ORCPT + 99 others); Sat, 12 Aug 2023 16:06:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231267AbjHLUGq (ORCPT ); Sat, 12 Aug 2023 16:06:46 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 171A5CE for ; Sat, 12 Aug 2023 13:06:23 -0700 (PDT) Message-ID: <20230812195729.272941596@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1691870363; 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=M3fEcYwRPucTriGvueSLaleqRSg7eLY3gJmW4uomGIVX9WE9SMJfOCwZ2EV678dR9kl8Vl 9L1iNrjD67+ttcDGCabe8/c7B0qkKC/hMZ1WEU+g3ecgVskuSH/xgFZNS99QmcI7sIxWJj ULoAudSVYwobcqzO4gKz+donjp57UHqewUqecssbw2bf+2uoluXxvz95X/0AfjBpbvvigM u7QQFTkpkj4cUijMHkTZbc2UiQjF5BP0z6N86qnuBkrHjEEcKosHzDhxjvQXgawzMXVqVS TRVeT4Dvla/1QdJnyIdQoAPrsgtxHIl7Zqzotpqgrs4/8xWLJoeIPdD2BRmd1w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1691870363; 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=pfJSr+h2nyv5sAeYgV/pAzJCqIOGswfWse3ifIJNdUM+3lUeo0OaZmeYXgNWR4BDiMDSXW x1+El5Imrg2oQUAg== From: Thomas Gleixner To: LKML Cc: x86@kernel.org, Borislav Petkov , Ashok Raj , Arjan van de Ven , Nikolay Borisov Subject: [patch V2 30/37] x86/microcode: Provide new control functions References: <20230812194003.682298127@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Date: Sat, 12 Aug 2023 21:59:23 +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,URIBL_BLOCKED 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 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();