From nobody Sat Sep 13 22:27:33 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0BF86C54EAA for ; Mon, 30 Jan 2023 16:17:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235938AbjA3QRY (ORCPT ); Mon, 30 Jan 2023 11:17:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52262 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234818AbjA3QRT (ORCPT ); Mon, 30 Jan 2023 11:17:19 -0500 Received: from mail.skyhub.de (mail.skyhub.de [IPv6:2a01:4f8:190:11c2::b:1457]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F76176B2 for ; Mon, 30 Jan 2023 08:17:18 -0800 (PST) Received: from zn.tnic (p5de8e9fe.dip0.t-ipconnect.de [93.232.233.254]) (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 0AB6D1EC0662; Mon, 30 Jan 2023 17:17:17 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alien8.de; s=dkim; t=1675095437; 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=8di1DcnjPBJs+6sR+q46scxgOm64hQ6Nc0v1gDxBPOQ=; b=kbOYdYxLjuSUHcotOBWNPGUcLBj0XhcknRBh57PVD4lt4cuJ1o+eXgSuU+xjCRrRt+5rRz c12g2PGtCToU8+7JVwFv9ON0bMyvxJOq1JaZuBbVeO8dNLUQkDfAIcm8rmIM7sMuVk0+/L hPcev2GG1vnTDjiqHAvlO3F/H3Md9BY= From: Borislav Petkov To: X86 ML Cc: LKML , stable@kernel.org Subject: [PATCH 3/4] x86/microcode/AMD: Fix mixed steppings support Date: Mon, 30 Jan 2023 17:17:08 +0100 Message-Id: <20230130161709.11615-4-bp@alien8.de> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20230130161709.11615-1-bp@alien8.de> References: <20230130161709.11615-1-bp@alien8.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: "Borislav Petkov (AMD)" The AMD side of the loader has always claimed to support mixed steppings. But somewhere along the way, it broke that by assuming that the cached patch blob is a single one instead of it being one per *node*. So turn it into a per-node one so that each node can stash the blob relevant for it. [ NB: Fixes tag is not really the exactly correct one but it is good enough. ] Fixes: fe055896c040 ("x86/microcode: Merge the early microcode loader") Signed-off-by: Borislav Petkov (AMD) Cc: --- arch/x86/kernel/cpu/microcode/amd.c | 34 ++++++++++++++++++----------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/micr= ocode/amd.c index b8d73f133193..ac59783e6e9f 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -55,7 +55,9 @@ struct cont_desc { }; =20 static u32 ucode_new_rev; -static u8 amd_ucode_patch[PATCH_MAX_SIZE]; + +/* One blob per node. */ +static u8 amd_ucode_patch[MAX_NUMNODES][PATCH_MAX_SIZE]; =20 /* * Microcode patch container file is prepended to the initrd in cpio @@ -428,7 +430,7 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode,= size_t size, bool save_p patch =3D (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch); #else new_rev =3D &ucode_new_rev; - patch =3D &amd_ucode_patch; + patch =3D &amd_ucode_patch[0]; #endif =20 desc.cpuid_1_eax =3D cpuid_1_eax; @@ -580,10 +582,10 @@ int __init save_microcode_in_initrd_amd(unsigned int = cpuid_1_eax) =20 void reload_ucode_amd(unsigned int cpu) { - struct microcode_amd *mc; u32 rev, dummy __always_unused; + struct microcode_amd *mc; =20 - mc =3D (struct microcode_amd *)amd_ucode_patch; + mc =3D (struct microcode_amd *)amd_ucode_patch[cpu_to_node(cpu)]; =20 rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); =20 @@ -851,6 +853,8 @@ static enum ucode_state __load_microcode_amd(u8 family,= const u8 *data, =20 static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size= _t size) { + struct cpuinfo_x86 *c; + unsigned int nid, cpu; struct ucode_patch *p; enum ucode_state ret; =20 @@ -863,18 +867,22 @@ static enum ucode_state load_microcode_amd(u8 family,= const u8 *data, size_t siz return ret; } =20 - p =3D find_patch(0); - if (!p) { - return ret; - } else { - if (boot_cpu_data.microcode >=3D p->patch_id) - return ret; + for_each_node(nid) { + cpu =3D cpumask_first(cpumask_of_node(nid)); + c =3D &cpu_data(cpu); + + p =3D find_patch(cpu); + if (!p) + continue; + + if (c->microcode >=3D p->patch_id) + continue; =20 ret =3D UCODE_NEW; - } =20 - memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); - memcpy(amd_ucode_patch, p->data, min_t(u32, p->size, PATCH_MAX_SIZE)); + memset(&amd_ucode_patch[nid], 0, PATCH_MAX_SIZE); + memcpy(&amd_ucode_patch[nid], p->data, min_t(u32, p->size, PATCH_MAX_SIZ= E)); + } =20 return ret; } --=20 2.35.1