From patchwork Wed Oct 19 17:54:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Borislav Petkov X-Patchwork-Id: 5799 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp462912wrs; Wed, 19 Oct 2022 11:03:12 -0700 (PDT) X-Google-Smtp-Source: AMsMyM63cbiPguvt0gb+UVAPv8EnD4UfeceaaKCqQyTw6i0LByoN4q0WXAqrp4683t4/3LR+HgDX X-Received: by 2002:a50:fb0f:0:b0:458:df03:c3aa with SMTP id d15-20020a50fb0f000000b00458df03c3aamr8483279edq.83.1666202592179; Wed, 19 Oct 2022 11:03:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666202592; cv=none; d=google.com; s=arc-20160816; b=AXX9bovKuYUAm7sRf/gEBCXURBeCdCiP69xpr5L4aL4i2kx/R6GiPQpYQVrC1rHWQz uf03gasmG3P9YxFFyXe2AJmZ4Bq8Tg0/pAxaWCx6k5G8lp2cIw0CEy6icaV/SXsgWiTN 5shL8OqCu/oTONKCJTSwka/kjGe9CrAJW2rUexi3E6noyvOza6UOFvFcWqgiTUhAsRHX jb2onqMmZgG2Z8BIeq3FxfcV75MX5rPZOPNVm9HjAv2qpUpRMPXnNB3Mp/Qh+qc2fcCu +j8ARddK4FcQ8cCvm+LjTYJ+TVbnaJOaV2HFjzeaRdxqkXulmdd7bDI4hKKX2DvSVhiS YsyQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ice+Zpi8zqJzSIBZbKVrhqcEXHbvGajZDt3Qb7Qrcbw=; b=sjEh1pRxrSdaa9GbtisFnMsnK21lR4ItJ/wrCpLuJd5DsrWbByVyeeAeotGr5QhDyy 7fEg+pYXbXyu9WD7bVdRxULzayb6GdTbbleefmRX1VInVJKiZLHdVHEW6yqmrNIMwlBV Ned/VSDFpWn3Y9YF5kYwykN3LIkIViMTbPpx7ikYrJSGT/ZbOFJ0Ba0aKY7Wz1VPv379 gX4vTQTFhXbvWCgifQyP6Q5RLKUO/1JAyD62bopL2bXjW0PgOdSQnbeC/O9+491mqepi svmwGa3pMLXxHdhZdtHm5WOEt5MH/Qh3AcXNRkOHS+OWTSlxzIQWx2xQ2LvFjbqzWrln p6fw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@alien8.de header.s=dkim header.b=jKjaecV5; 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=NONE dis=NONE) header.from=alien8.de Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u26-20020a056402065a00b004514cd5ec24si13635533edx.630.2022.10.19.11.02.24; Wed, 19 Oct 2022 11:03:12 -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=@alien8.de header.s=dkim header.b=jKjaecV5; 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=NONE dis=NONE) header.from=alien8.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230175AbiJSRyi (ORCPT + 99 others); Wed, 19 Oct 2022 13:54:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59464 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229732AbiJSRyf (ORCPT ); Wed, 19 Oct 2022 13:54:35 -0400 Received: from mail.skyhub.de (mail.skyhub.de [5.9.137.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3873C11A1B for ; Wed, 19 Oct 2022 10:54:29 -0700 (PDT) Received: from zn.tnic (p200300ea9733e7c5329c23fffea6a903.dip0.t-ipconnect.de [IPv6:2003:ea:9733:e7c5:329c:23ff:fea6:a903]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.skyhub.de (SuperMail on ZX Spectrum 128k) with ESMTPSA id 5765F1EC0715; Wed, 19 Oct 2022 19:54:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alien8.de; s=dkim; t=1666202068; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ice+Zpi8zqJzSIBZbKVrhqcEXHbvGajZDt3Qb7Qrcbw=; b=jKjaecV5WEdb4cujmDjYvR2CCmguOOuhdR+mtB9OD8y+m78filHR9OpVZzZ9SVjRM60ccw 0Gzuuw2DEHBisWYROPg1GJZ0SIDf8aaRUz3vG7KnXE7IteJ8+g3ZzHvoPbk8vMu74sLlQp HUByZi3iik6cBMQR3FhDPS/nAo72OoM= From: Borislav Petkov To: Ashok Raj Cc: Tony Luck , Tom Lendacky , Arjan van de Ven , Jacob Jun Pan , X86 ML , LKML Subject: [PATCH 2/5] x86/microcode: Simplify init path even more Date: Wed, 19 Oct 2022 19:54:23 +0200 Message-Id: <20221019175426.31025-2-bp@alien8.de> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221019175426.31025-1-bp@alien8.de> References: <20221019175426.31025-1-bp@alien8.de> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,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 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747140048939576698?= X-GMAIL-MSGID: =?utf-8?q?1747140048939576698?= From: Borislav Petkov Get rid of all the IPI-sending functions and their wrappers and use those which are supposed to be called on each CPU. Thus: - microcode_init_cpu() gets called on each CPU on init, applying any new microcode that the driver might've found on the filesystem. - mc_cpu_starting() simply tries to apply cached microcode as this is the cpuhp starting callback which gets called on CPU resume too. And since the driver init function is a late initcall, there is filesystem by then so a new firmware load attempt can simply be done. In case a new one is there. Which is weird to begin with - how would the initrd contain an older revision than what's on the fs since former gets created by using the blobs from the filesystem. Oh well, it is cheap to do so why not... Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/microcode/core.c | 127 +++++---------------------- 1 file changed, 23 insertions(+), 104 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index a3aedc93afd9..0aa6609e748c 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -319,60 +319,6 @@ void reload_early_microcode(void) } } -static void collect_cpu_info_local(void *arg) -{ - struct cpu_info_ctx *ctx = arg; - - ctx->err = microcode_ops->collect_cpu_info(smp_processor_id(), - ctx->cpu_sig); -} - -static int collect_cpu_info_on_target(int cpu, struct cpu_signature *cpu_sig) -{ - struct cpu_info_ctx ctx = { .cpu_sig = cpu_sig, .err = 0 }; - int ret; - - ret = smp_call_function_single(cpu, collect_cpu_info_local, &ctx, 1); - if (!ret) - ret = ctx.err; - - return ret; -} - -static int collect_cpu_info(int cpu) -{ - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - int ret; - - memset(uci, 0, sizeof(*uci)); - - ret = collect_cpu_info_on_target(cpu, &uci->cpu_sig); - if (!ret) - uci->valid = 1; - - return ret; -} - -static void apply_microcode_local(void *arg) -{ - enum ucode_state *err = arg; - - *err = microcode_ops->apply_microcode(smp_processor_id()); -} - -static int apply_microcode_on_target(int cpu) -{ - enum ucode_state err; - int ret; - - ret = smp_call_function_single(cpu, apply_microcode_local, &err, 1); - if (!ret) { - if (err == UCODE_ERROR) - ret = 1; - } - return ret; -} - /* fake device for request_firmware */ static struct platform_device *microcode_pdev; @@ -458,7 +404,7 @@ static int __reload_late(void *info) * below. */ if (cpumask_first(topology_sibling_cpumask(cpu)) == cpu) - apply_microcode_local(&err); + err = microcode_ops->apply_microcode(cpu); else goto wait_for_siblings; @@ -480,7 +426,7 @@ static int __reload_late(void *info) * revision. */ if (cpumask_first(topology_sibling_cpumask(cpu)) != cpu) - apply_microcode_local(&err); + err = microcode_ops->apply_microcode(cpu); return ret; } @@ -589,51 +535,15 @@ static void microcode_fini_cpu(int cpu) microcode_ops->microcode_fini_cpu(cpu); } -static enum ucode_state microcode_resume_cpu(int cpu) -{ - if (apply_microcode_on_target(cpu)) - return UCODE_ERROR; - - pr_debug("CPU%d updated upon resume\n", cpu); - - return UCODE_OK; -} - -static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw) -{ - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - enum ucode_state ustate; - - if (uci->valid) - return UCODE_OK; - - if (collect_cpu_info(cpu)) - return UCODE_ERROR; - - /* --dimm. Trigger a delayed update? */ - if (system_state != SYSTEM_RUNNING) - return UCODE_NFOUND; - - ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev, refresh_fw); - if (ustate == UCODE_NEW) { - pr_debug("CPU%d updated upon init\n", cpu); - apply_microcode_on_target(cpu); - } - - return ustate; -} - -static enum ucode_state microcode_update_cpu(int cpu) +static enum ucode_state microcode_init_cpu(int cpu) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - /* Refresh CPU microcode revision after resume. */ - collect_cpu_info(cpu); + memset(uci, 0, sizeof(*uci)); - if (uci->valid) - return microcode_resume_cpu(cpu); + microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); - return microcode_init_cpu(cpu, false); + return microcode_ops->apply_microcode(cpu); } /** @@ -651,14 +561,14 @@ void microcode_bsp_resume(void) } static struct syscore_ops mc_syscore_ops = { - .resume = microcode_bsp_resume, + .resume = microcode_bsp_resume, }; static int mc_cpu_starting(unsigned int cpu) { - microcode_update_cpu(cpu); - pr_debug("CPU%d added\n", cpu); - return 0; + enum ucode_state err = microcode_ops->apply_microcode(cpu); + + return err == UCODE_ERROR; } static int mc_cpu_online(unsigned int cpu) @@ -688,11 +598,13 @@ static int mc_cpu_down_prep(unsigned int cpu) static void setup_online_cpu(void *info) { int cpu = smp_processor_id(); - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - - memset(uci, 0, sizeof(*uci)); + enum ucode_state err; - microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); + err = microcode_init_cpu(cpu); + if (err == UCODE_ERROR) { + pr_err("Error applying microcode on CPU%d\n", cpu); + return; + } mc_cpu_online(cpu); } @@ -740,6 +652,13 @@ static int __init microcode_init(void) goto out_pdev; } + /* + * Try to load microcode once on the BSP in case the initrd has older revision. + * Frankly, I have no clue how that can happen but hey, loading here is cheap so + * why not. + */ + microcode_ops->request_microcode_fw(boot_cpu_data.cpu_index, µcode_pdev->dev, true); + /* Do per-CPU setup */ cpus_read_lock(); on_each_cpu(setup_online_cpu, NULL, 0);