From patchwork Mon Oct 2 12:00:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 147289 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2a8e:b0:403:3b70:6f57 with SMTP id in14csp1419816vqb; Mon, 2 Oct 2023 06:17:10 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGDRh6ned4WsZvgml3tiet6mblIFOpW4bVRUcqhCYUTaArhDnsYvoWoRPJQCw3oXWZMqN6V X-Received: by 2002:a17:90a:17a2:b0:277:2d7c:1be4 with SMTP id q31-20020a17090a17a200b002772d7c1be4mr10204891pja.1.1696252630367; Mon, 02 Oct 2023 06:17:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1696252630; cv=none; d=google.com; s=arc-20160816; b=XLRDZ5NH2qD0ZYuHI3u56crMMjOuDFriPUxTFtRBJWsV4pkVFG0gD5feu5CYUgU8Ph +Ar73PqU8R3AJwuujBGwcziOxXossmUO92iDJhYwq21OkkzroE1q/xX2N4STi6pl8Wx2 a7VSm2UkMJUG0/nqbO7udW4iP3WLlnn1mEw01fiiirKEuQNG/5hHws4cttgkN3mgtC93 WlYgjWh56cnwY2mkiaiNyhnKcdTkbdKX8dUnIGPRbeVFcynOkFuF1INTXrxUp/fLbnfN URkrhUuMfFvSqnpoNnZXmPhfyjoi7XJeUkDEnoHp0NhVaZvanxVvCUATydVER9G1PCyv NXhw== 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=p686dGKnLUGiOBuJ3ZmFJ4Qfbmz+TWkPBvmKkOJ7OCc=; fh=u57tXYamzTrJA+Ht8n1u7SfTMptrQaIb6LVW+jsaYf4=; b=zpZ01quO9Q1Js1iZfrdAT/VWthU35Gc9JRKUwTVzN5RM9ibLRMYmHs5YuShO6VKZIo aImhAtU8IpZ7yhkDbYDulr9lTKNQWCMpDCw9kKIbAKtiwz/IHYIrX7E3qPO1KFPCtWeC FTQXQF/7AP4mto/zEcHSng5XRwM2j7nh9/HTbJ/zbgjX+Rm4buOYwq3t7MiAK3/IdLn8 IWZLydJn6ZPr8YMZBxbzSK68mkMh8ySIZRkr1nNBGwGge/+SvSlYYvs3NwFT/IKF7DRg ExxvthSngaJY1T+sT3HCip2TArgYSGOHxryiLiCivCRs2nbUtNSBUpr6iAdKMSkvJ8Ja SGhg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=SPqIhS1h; dkim=neutral (no key) header.i=@linutronix.de header.b=WmdkA0xp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 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 lipwig.vger.email (lipwig.vger.email. [2620:137:e000::3:3]) by mx.google.com with ESMTPS id om13-20020a17090b3a8d00b002790b1320d4si8143330pjb.84.2023.10.02.06.17.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Oct 2023 06:17:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) client-ip=2620:137:e000::3:3; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=SPqIhS1h; dkim=neutral (no key) header.i=@linutronix.de header.b=WmdkA0xp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 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 lipwig.vger.email (Postfix) with ESMTP id 7882C807E937; Mon, 2 Oct 2023 05:01:29 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237003AbjJBMAy (ORCPT + 18 others); Mon, 2 Oct 2023 08:00:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46122 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236983AbjJBMAZ (ORCPT ); Mon, 2 Oct 2023 08:00:25 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97669CF3 for ; Mon, 2 Oct 2023 05:00:04 -0700 (PDT) Message-ID: <20231002115903.377922731@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1696248002; 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=p686dGKnLUGiOBuJ3ZmFJ4Qfbmz+TWkPBvmKkOJ7OCc=; b=SPqIhS1hrgF2dkqtk/+E/F0nA3bJ4MDo+PwLvXGME2dgr7O8LbXe3/8abKLvmTN6fe1xHC K3hCNngS+/8ca/hRZOWgQPhOpm5Gq5UXia+eY5x4Ws3vIKhDpdTj9lNWmfaionaGBcXEqo K9KDHcVpvQBczZ8tr3WQ5ghm9TLctmpv+33X/FGXO2s9FpDAGv0G65r53hofeFP67OdSmH jiH/x9qtkRbE2S8JlqOBEtusSp3SsAfxz3NXrR5gN/q8CMahquCfkeB8uRFpxGbyabqzzB 3+SEDyr9cpK4wdHuyg7eZrpJnYoRG24A5QdvLcfvKWdN+JLEwq6JrtijlQxSmw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1696248002; 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=p686dGKnLUGiOBuJ3ZmFJ4Qfbmz+TWkPBvmKkOJ7OCc=; b=WmdkA0xpYnMj5C2a8Q91uUzS8bCPoIvxADv7s9Fh2OTUIEa85bY2tcN1Zr7Ja3Vqt8GnN+ gWeq3LxnSWCMeXCg== From: Thomas Gleixner To: LKML Cc: x86@kernel.org, Borislav Petkov , "Chang S. Bae" , Arjan van de Ven , Nikolay Borisov Subject: [patch V4 23/30] x86/microcode: Provide new control functions References: <20231002115506.217091296@linutronix.de> MIME-Version: 1.0 Date: Mon, 2 Oct 2023 14:00:02 +0200 (CEST) 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 lipwig.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 (lipwig.vger.email [0.0.0.0]); Mon, 02 Oct 2023 05:01:29 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1778649797995562767 X-GMAIL-MSGID: 1778649797995562767 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 rendezvouz 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 | 84 +++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) --- --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -319,6 +319,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 rendezvouz 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 rendezvouz 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();