From nobody Sat Sep 26 11:46:59 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB2353D567F; Tue, 1 Sep 2026 23:43:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306199; cv=none; b=Q4+VAT0WrTQEZz25nQx66KVY9BVPrl4oKt47a3qJ/iCr2vfYypDw8nGZyU3ewiNFLfl5bYkqjl5OWfBYuU1Tej037LjtjThKcpOxSlNMmGyzEEyBCOX2Op4f55ALiiRIJ3TTXI8Fo+UQyWcyjEgr7yf4a1sq0ehDd2EacTGNpTA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306199; c=relaxed/simple; bh=aNne2qQnrJg4PvKvtwhkwuzAaor7MUDU122PMGNWSP4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=vDTUjkJnUoYNcwgZoiWGMXCJL61/PHwf7zXwunYA1hPO6vOWrjyFHBffNkybi7C2IKtEOaByllaAHPFScHqdX0KwYAlk5Y7PjL5bIRyU4IrsSoO6MzZEKLQ9mbu/5CSOYY4Ds3+EpMY/zAm1XfY0ZXJx+HiAZD9C7Csmo9S0cdg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=HZxQSoI0; arc=none smtp.client-ip=192.198.163.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="HZxQSoI0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1788306197; x=1819842197; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=aNne2qQnrJg4PvKvtwhkwuzAaor7MUDU122PMGNWSP4=; b=HZxQSoI0Nj1EO9mJe1U+qeRy+3NL51alEObu3XQcBSaI+9TR8bmM+u5d jug1A0YuPptljhunvB3gHl+vymLv2p5zm5+UYS/twczi14YiTXUyMVUbE eTcM0IA1PjvhrtOpODhF0ybF1ekWDiUZIJZH1eIpe1/UUDNLiFmFtjmfr oeytsuGJrQ+nOCIB5V59MxH0lkjJXAf7yxvACcGWVRE02w6GUvl6OH8bd XVoc4uYUCWtkQZAq0uSdoafr0UcJ49HNYe5KqBKGSOIGhjBgan9jvM2OY SjMRuvoi5iohhj//AWd5eJAlB/JZDbzRqgpxRJri+Y9ujncxpH0Md234j w==; X-CSE-ConnectionGUID: Yajtoyy3QymM/kEOpXEFkg== X-CSE-MsgGUID: DblhapU/Ri68kdgCC/2Y1g== X-IronPort-AV: E=McAfee;i="6800,10657,11893"; a="87891863" X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="87891863" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa112.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2026 16:43:16 -0700 X-CSE-ConnectionGUID: LVt2cL9dRb2r7JB353YNPQ== X-CSE-MsgGUID: WGI/GBHvR8O2CWQwPQ1WJA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="267469876" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa006.jf.intel.com with ESMTP; 01 Sep 2026 16:43:16 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, andrew.cooper3@citrix.com, arjan.van.de.ven@intel.com, chang.seok.bae@intel.com, stable@vger.kernel.org Subject: [PATCH 1/8] x86/microcode/intel: Reject problematic loading on GNR systems Date: Tue, 1 Sep 2026 23:16:26 +0000 Message-ID: <20260901231634.714144-2-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260901231634.714144-1-chang.seok.bae@intel.com> References: <20260901231634.714144-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Revision 0x1000405 contains internal microcode changes that are required by subsequent revisions to avoid #MC during loading. This dependency logically fits the minimum revision requirement. The minimum revision check, however, currently applies only to the late loading path, since the dependency was primarily intended for OS-visible changes. The early loading path is therefore still vulnerable to this issue. Furthermore, one of the subsequent revisions does not correctly specify the minimum revision, so unfortunately the late loading cannot rely on that check either in this case. Prevent loading 0x1000405 or later when the system has not yet been updated to 0x1000405 or later. Apply this blocking to both early- and late-loading paths. Rename is_blacklisted() to is_late_loading_denied() so the new function that covers both loading paths is not confused with the late-load only one. Signed-off-by: Chang S. Bae Cc: --- The GNR errata page: https://edc.intel.com/content/www/jp/ja/design/products-and-solutions/proce= ssors-and-chipsets/birch-stream/xeon-6900-6700-6500-series-processors-with-= p-cores-specification-update/016US/errata-summary-table/ Thanks to Sohil, I noticed the naming guideline in Documentation/process/coding-style.rst: For symbol names and documentation, avoid introducing new usage of 'master / slave' (or 'slave' independent of 'master') and 'blacklist / whitelist'. --- arch/x86/kernel/cpu/microcode/intel.c | 42 +++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/mi= crocode/intel.c index 1142183c950c..c502138fd8e9 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -309,6 +309,38 @@ static void save_microcode_patch(struct microcode_inte= l *patch) pr_err("Unable to allocate microcode memory size: %u\n", size); } =20 +static bool is_loading_denied(struct cpu_signature *sig, u32 rev) +{ + u32 vfm =3D IFM(x86_family(sig->sig), x86_model(sig->sig)); + + /* + * Revision 0x1000405 contains prerequisite changes for subsequent + * microcode updates on Granite Rapids systems. Updates directly from + * an older revision to this or a newer one can result in #MC (GNR98). + * + * This dependency can be indicated from the minimum revision field. + * However, revision 0x1000423 has an incorrect minimum revision in its + * header (GNR101). + * + * Prevent loading 0x1000405 or later unless the CPU has already been + * updated to 0x1000405 or later. + */ + if (vfm =3D=3D INTEL_GRANITERAPIDS_X && + x86_stepping(sig->sig) =3D=3D 1 && + sig->pf & 0x95 && + sig->rev < 0x1000405 && + rev >=3D 0x1000405) { + if (rev =3D=3D 0x1000405) + pr_err_once("Erratum GNR98: 0x1000405 is not loadable.\n"); + else + pr_err_once("Erratum GNR98: 0x1000405 is required before 0x%x.\n", rev); + pr_err_once("Please update the system BIOS or firmware.\n"); + return true; + } + + return false; +} + /* Scan blob for microcode matching the boot CPUs family, model, stepping = */ static __init struct microcode_intel *scan_microcode(void *data, size_t si= ze, struct ucode_cpu_info *uci, @@ -330,6 +362,9 @@ static __init struct microcode_intel *scan_microcode(vo= id *data, size_t size, if (!intel_find_matching_signature(data, &uci->cpu_sig)) continue; =20 + if (is_loading_denied(&uci->cpu_sig, mc_header->rev)) + continue; + /* * For saving the early microcode, find the matching revision which * was loaded on the BSP. @@ -878,6 +913,9 @@ static enum ucode_state parse_microcode_blobs(int cpu, = struct iov_iter *iter) if (!intel_find_matching_signature(mc, &uci->cpu_sig)) continue; =20 + if (is_loading_denied(&uci->cpu_sig, mc_header.rev)) + continue; + is_safe =3D ucode_validate_minrev(&mc_header); if (force_minrev && !is_safe) continue; @@ -905,7 +943,7 @@ static enum ucode_state parse_microcode_blobs(int cpu, = struct iov_iter *iter) return UCODE_ERROR; } =20 -static bool is_blacklisted(unsigned int cpu) +static bool is_late_loading_denied(unsigned int cpu) { struct cpuinfo_x86 *c =3D &cpu_data(cpu); =20 @@ -936,7 +974,7 @@ static enum ucode_state request_microcode_fw(int cpu, s= truct device *device) struct kvec kvec; char name[30]; =20 - if (is_blacklisted(cpu)) + if (is_late_loading_denied(cpu)) return UCODE_NFOUND; =20 sprintf(name, "intel-ucode/%02x-%02x-%02x", --=20 2.53.0 From nobody Sat Sep 26 11:46:59 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A50B6473C65; Tue, 1 Sep 2026 23:43:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306200; cv=none; b=CwlNRlltTZ14Gj5pyqSyR1db2uM7Yv7otrhY495Zt/TAdqQa+3RPqhGe4AdFdyACdNSpf1fVjiwN6J8v6MUqW5Wxt16Z19ngR0ZGitCVI1oCz8E9dB3ghCErHYb8cfYBAJEKJsmzFpNKniMgzTijnqPack6xdstzFADeEigO0Q4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306200; c=relaxed/simple; bh=f3hDoqQQZ6E3UtV7iDJbCgMiPOrej6NW5ioW9NE92Ts=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KmEh00P+Osaw0kBKSSm3fWnpUPAOlLHUbZOFHoFVYwpmgUMZ++/dF/kM2/yao+2yAn+YygeurMGCxMaRmng0m2QPBiz0KFuu0p4Kho/+YhJInLm2sr1Rf1KzPFP3Rg0GKNCH+Xo5r+wI6/O5bEe6Ukj72l5c1xgUGPNHdBH18Zg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=QCbR7LTi; arc=none smtp.client-ip=192.198.163.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="QCbR7LTi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1788306199; x=1819842199; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=f3hDoqQQZ6E3UtV7iDJbCgMiPOrej6NW5ioW9NE92Ts=; b=QCbR7LTiM/AeCXuLwCYcMU7UG43jGYca1TjbTCFLTfLIhWh8GZKQjvl9 iPtaupF3V5oomSGHOTTZQw6KDkZFRRQ2XrsGY5cq31um9GwS/j1LVPRk1 NMaNiIXAkWIvzq7UHS+6Ok9etyZfOsUMubDIP5XfQZ6Ga9gdMZECnwuTl cpgDyYtrUT1Nb1ev7bE0KzP3HzVFO0BgG6ppsrr4NCJFUrwmRhaou6oR1 CByT2KwvFT42CdDJ/1f8JvM2mUjrfeAWdw87T7FgIZheE3j9TFvZYNerf 8suMjlrQfngvclsbL6Cm3VCtzXWy4+xkf1nEsFjyLJaivC8mmB55sss8c g==; X-CSE-ConnectionGUID: PpeKUv6eQgGtzbca+tiGQA== X-CSE-MsgGUID: 0Va/iHw7QX+p8Pdgt/1Dpw== X-IronPort-AV: E=McAfee;i="6800,10657,11893"; a="87891871" X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="87891871" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa112.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2026 16:43:18 -0700 X-CSE-ConnectionGUID: VP+xokYwTAu9n0eLool9xQ== X-CSE-MsgGUID: mGJXpxTRQs6rVyAjOyL2yQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="267469882" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa006.jf.intel.com with ESMTP; 01 Sep 2026 16:43:18 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, andrew.cooper3@citrix.com, arjan.van.de.ven@intel.com, chang.seok.bae@intel.com, stable@vger.kernel.org Subject: [PATCH 2/8] x86/microcode: Solidify base_rev= option parsing Date: Tue, 1 Sep 2026 23:16:27 +0000 Message-ID: <20260901231634.714144-3-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260901231634.714144-1-chang.seok.bae@intel.com> References: <20260901231634.714144-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" After base_rev=3D has been parsed, the remainder of the token is still compared against the other option names. Along with this, the substring check strstr() may also produce a spurious match. Move on to the next token once the option has been parsed, and use str_has_prefix() instead. Fixes: 43181a47263d ("x86/microcode: Add microcode loader debugging functio= nality") Signed-off-by: Chang S. Bae Cc: --- arch/x86/kernel/cpu/microcode/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/mic= rocode/core.c index 0dd0c7241c57..303b0d0b4573 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -146,10 +146,11 @@ static void __init early_parse_cmdline(void) if (cmdline_find_option(boot_command_line, "microcode", cmd_buf, sizeof(c= md_buf)) > 0) { while ((s =3D strsep(&p, ","))) { if (IS_ENABLED(CONFIG_MICROCODE_DBG)) { - if (strstr(s, "base_rev=3D")) { + if (str_has_prefix(s, "base_rev=3D")) { /* advance to the option arg */ strsep(&s, "=3D"); if (kstrtouint(s, 16, &base_rev)) { ; } + continue; } } =20 --=20 2.53.0 From nobody Sat Sep 26 11:46:59 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 395D647B43E; Tue, 1 Sep 2026 23:43:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306203; cv=none; b=btoh+KIWUiiLTi4oFhdyaqRH1AgSH2mYMGNlnWcxBgh5YYgyUBwHkXD567PJYCAhgf3n++twtf5GaoRDiOaqoWdCLZNEOsqruHIlsNfsNSEePTcaJ7ru021J7ZARlL3iSAaZTqaE4MhqvU59sUm/c8shhmmrnydNY1mUyxN28Hs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306203; c=relaxed/simple; bh=qgjMoEhsz5XWG3TKtELCp4LZvgsKE9DAoHw3iYFjrDo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MHzkYyISsb1Dtftr7i7x2mIdIQTkit158z6XaphM0BIIxnCKrB3uX+VdAM3UTkAZUBTB3hqa0XUk1ApmR6tZh1AikXd+NuRFaGT30/IWShtic2tGE6C62lhkC2Pcxkd300YyZCQsqMSJ2z2a3irtourGsZ4szegir+6dJQTok20= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Im3L93Mf; arc=none smtp.client-ip=192.198.163.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Im3L93Mf" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1788306201; x=1819842201; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qgjMoEhsz5XWG3TKtELCp4LZvgsKE9DAoHw3iYFjrDo=; b=Im3L93MfrvOyGmyAYQ8EWkxUrcNt0e0h9cb0iNuYXYvdOhWyZCA/tdMx inz+TJFDfBKQOxRhLOoqEjSA5ZzM9F/rik/FaXnPfEzDCwqN9XCDUhA3K +9mh4iReDIYpMAzQ0cBupybc//s4yaH230TwjaqFduJrg6VNHEF/mcsPS JAEFILe/EIJFm/kcLZJc/V0MKiqc3sMgGTv5LltQPfKIWNShS6o7F91Kg zLeDINLYo0DKbU9HUlSk2yDSkAf08jHLJTxxs+4fP5c5sbtNhKIg5Eb8k rcU8vJvfRVXTtYCXeOp0/2bo4ALzmuX9iYdGUtoIeBv7EURLhFKZaPOmu A==; X-CSE-ConnectionGUID: zgXkM91YRg+89K04sZ8Y5g== X-CSE-MsgGUID: VqT+TzAZTCSZLS7PSMzSTg== X-IronPort-AV: E=McAfee;i="6800,10657,11893"; a="87891878" X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="87891878" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa112.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2026 16:43:21 -0700 X-CSE-ConnectionGUID: NjCiAyMaTWq/6V1lKCJ5yQ== X-CSE-MsgGUID: Tg9RllEtTxeDxcw9RVntig== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="267469888" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa006.jf.intel.com with ESMTP; 01 Sep 2026 16:43:21 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, andrew.cooper3@citrix.com, arjan.van.de.ven@intel.com, chang.seok.bae@intel.com, Sohil Mehta , stable@vger.kernel.org Subject: [PATCH 3/8] x86/microcode: Accept a boolean for force_minrev parameter Date: Tue, 1 Sep 2026 23:16:28 +0000 Message-ID: <20260901231634.714144-4-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260901231634.714144-1-chang.seok.bae@intel.com> References: <20260901231634.714144-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The microcode=3D command-line option allows controlling all microcode loading options. However, force_minrev can only enable minimum revision enforcement, not disable it. The previous microcode.force_minrev=3D option accepted both boolean values, and the current behavior differs from the documentation in kernel-parameters.txt. Add `force_minrev=3D` as a sub-option to explicitly enable or disable the minimum revision enforcement. Update the documentation accordingly. While doing so, wrap strsep() in a descriptively named helper. Fixes: 632ff6170647 ("x86/microcode: Add microcode=3D cmdline parsing") Reported-by: Sohil Mehta Signed-off-by: Chang S. Bae Cc: --- Documentation/admin-guide/kernel-parameters.txt | 7 ++++--- arch/x86/kernel/cpu/microcode/core.c | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentatio= n/admin-guide/kernel-parameters.txt index 68647ff4bdd2..cde092017cd8 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -4071,9 +4071,10 @@ Kernel parameters =20 dis_ucode_ldr: disable the microcode loader =20 - force_minrev: - Enable or disable the microcode minimal revision - enforcement for the runtime microcode loader. + force_minrev[=3D]: + Enable or disable microcode minimal revision enforcement + for the runtime microcode loader according to . If + is not given, enable the enforcement. =20 mini2440=3D [ARM,HW,KNL] Format:[0..2][b][c][t] diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/mic= rocode/core.c index 303b0d0b4573..af7196d94540 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -138,6 +138,11 @@ bool __init microcode_loader_disabled(void) return dis_ucode_ldr; } =20 +static inline void advance_option_argument(char **s) +{ + strsep(s, "=3D"); +} + static void __init early_parse_cmdline(void) { char cmd_buf[64] =3D {}; @@ -147,15 +152,19 @@ static void __init early_parse_cmdline(void) while ((s =3D strsep(&p, ","))) { if (IS_ENABLED(CONFIG_MICROCODE_DBG)) { if (str_has_prefix(s, "base_rev=3D")) { - /* advance to the option arg */ - strsep(&s, "=3D"); + advance_option_argument(&s); if (kstrtouint(s, 16, &base_rev)) { ; } continue; } } =20 - if (!strcmp("force_minrev", s)) + if (!strcmp("force_minrev", s)) { force_minrev =3D true; + } else if (str_has_prefix(s, "force_minrev=3D")) { + advance_option_argument(&s); + if (kstrtobool(s, &force_minrev)) { ; } + continue; + } =20 if (!strcmp(s, "dis_ucode_ldr")) dis_ucode_ldr =3D true; --=20 2.53.0 From nobody Sat Sep 26 11:46:59 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D5A14A441F for ; Tue, 1 Sep 2026 23:43:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306205; cv=none; b=HgmowCUkIyhlNpgtQUUZGJ6hfYIcDHmsIn6beDNaVMqVUUaq3JYwateThjXKHzXsNqGHBRVEF8Zx2D3uaHExIawhbus2zWuVlMGeX86WZqkAZsoKuS5kY+IYhtH/q82TPry2V5aPMQen6N8yJid/MNPu4jtRDg7mgwSljxL80dA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306205; c=relaxed/simple; bh=kyl9h0+pSAZsZXBPZmOA0Ouninh5cmHwYUrBFiq63S0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZkwMk3VLJOVWjBjiPEjYaISsQnnbX1SCHdE4QJ59sOaf1CES+hBZ2xHFNQyxJwbSPDyxzXJHBvbR/xyRG+ycCv58hUdqV6gBOoNf1XzOeOsqH3tNs859F7sRnbcqWu4cmjWPh7TcESYEbxBSuLaDLJY+In2jhm7t0Cgy5QtQPCU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=YL+/WNO+; arc=none smtp.client-ip=192.198.163.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="YL+/WNO+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1788306204; x=1819842204; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kyl9h0+pSAZsZXBPZmOA0Ouninh5cmHwYUrBFiq63S0=; b=YL+/WNO+FJntIqj0N5EsU6oEAb8CD3mX94ld9Ln/lxpHN2RB+uAu+mAr Y7YSN7VXz/uww8is1Ku3Ge3fhtf2fkVJBBXJPqYEEGXt1kHu015zmHLWD 2uRG192kbQmMDaskN98Fii2QwI3icZk6HqueGauR+SOg+DtULp4Ne2hn+ WZmLeMv/S+Si2WJmOJkSQj0JQ8VFJ8l9BYHeLh6H9MyrMvOtcIwYbQAoT QYIkJHXhLfO+AGcsKweNp5Ny8G4hmIugV1wCYkHsuHEzmz/uETnBHWngo iM7zKj96Knm0g1/fXJdft8OL+g9+QPimjWNgK/JYpbhHVrD0O9vIgkJdG w==; X-CSE-ConnectionGUID: PC5bXYeGRRCEk55KXFBSnw== X-CSE-MsgGUID: kRKvUiUqSDaj+35gG4kwew== X-IronPort-AV: E=McAfee;i="6800,10657,11893"; a="87891885" X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="87891885" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa112.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2026 16:43:22 -0700 X-CSE-ConnectionGUID: dYjgyBq6RTe1amRy06oVyA== X-CSE-MsgGUID: saeT48teRc2+dMnLXe9Exg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="267469897" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa006.jf.intel.com with ESMTP; 01 Sep 2026 16:43:22 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, andrew.cooper3@citrix.com, arjan.van.de.ven@intel.com, chang.seok.bae@intel.com Subject: [PATCH 4/8] x86/microcode: Mark early_data __initdata Date: Tue, 1 Sep 2026 23:16:29 +0000 Message-ID: <20260901231634.714144-5-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260901231634.714144-1-chang.seok.bae@intel.com> References: <20260901231634.714144-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" early_data records the revisions seen during early loading, and microcode_init() is its last reader. Mark the storage reclaimable afterwards. Signed-off-by: Chang S. Bae --- arch/x86/kernel/cpu/microcode/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/mic= rocode/core.c index af7196d94540..ed1eb6b753d6 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -83,7 +83,7 @@ static u32 final_levels[] =3D { 0, /* T-101 terminator */ }; =20 -struct early_load_data early_data; +struct early_load_data early_data __initdata; =20 /* * Check the current patch level on this CPU. --=20 2.53.0 From nobody Sat Sep 26 11:46:59 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 13EBA4A441D for ; Tue, 1 Sep 2026 23:43:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306205; cv=none; b=i7O/qC7SgW0xrRgEGY3sl0W149t5ytceQqlybjnkLwIRzIf1+aQcP8LcE+uZkFcoNP70XEL3Gbdzd5PlYnJ64ad3JEVhjXHMcrzA1hvo0ghmPmEiB4+HTtsZ6+LA7WQHiVdSMVgeYZacBNZD853EfaidrK5Ehi/0Ne2kNfQv0UU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306205; c=relaxed/simple; bh=tAaLoUhI728wDlwgEmOtvEJGL4lrrkrloUQyfXITh1E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X0oW/Ij8uHBkbElaeCfzYntli7lw+jFcWv/52sMXZwcOEjvuWgyf5U8Ahv/VoHXq3LJqmldjPx1DOnNf6GA14pCWeqbUrXolILnYr1NZeNPJxxgjboQhZEjOyBDWRVBB3cKyQODkTbfG+wGnfD9m4plDuREhrdrfdo79ToLpAvA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=GAKFFdYP; arc=none smtp.client-ip=192.198.163.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="GAKFFdYP" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1788306204; x=1819842204; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tAaLoUhI728wDlwgEmOtvEJGL4lrrkrloUQyfXITh1E=; b=GAKFFdYPj7+nP8wHQJuAL+ntX6ymLLrwf9eDIYGFuo7XUGEMuQ9SZT9/ wUCul0SEznEzcqBocWFPNxKQNSqDdbZdr1bVsiAob5t/3nB9GruGvE/Ke vRxgGLVo2YWMxitMXf6WBeUlZmaq/VOAejCv1UBTyCu4Boo3Y4B2jpJaF RCB/JoSg+frCr0heivlQ5D+bfi3dyfscI00I0IoMC/zzMONdpUomAQuuJ kkpVVrUTew2CihTy8fUHW0GA9NDlNB7z87ECzRaVjY2grrX5Xzti6wHiJ fAZmQ1LHM3h3ReyaCG/hJoQf6ULeiN8HIuKSJEEhD+81oQlaw+nN+DN8J A==; X-CSE-ConnectionGUID: pIgxfycAT8utuLWPNvolKA== X-CSE-MsgGUID: 6YzPI1kRQ9eR+FFQ2SzJyw== X-IronPort-AV: E=McAfee;i="6800,10657,11893"; a="87891892" X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="87891892" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa112.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2026 16:43:24 -0700 X-CSE-ConnectionGUID: 1vbDc5ACRfCeuHSXu2rUaw== X-CSE-MsgGUID: ApSTwKdURTeuCA+Q6cff7g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="267469903" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa006.jf.intel.com with ESMTP; 01 Sep 2026 16:43:24 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, andrew.cooper3@citrix.com, arjan.van.de.ven@intel.com, chang.seok.bae@intel.com Subject: [PATCH RFC 5/8] x86/microcode: Decouple minimum revision check from late loading Date: Tue, 1 Sep 2026 23:16:30 +0000 Message-ID: <20260901231634.714144-6-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260901231634.714144-1-chang.seok.bae@intel.com> References: <20260901231634.714144-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The microcode minimum revision check was originally introduced to express dependencies involving OS-visible changes, thus it has been limited to the late-load path. In fact this can serve as a general guard against unsafe microcode loading. Make the check independent of the loading path in preparation for applying it to the early path as well. For now, reject early loading if enforced. Taint the kernel on early loading because the early path does not perform the check yet. Signed-off-by: Chang S. Bae --- Note for the review: The AMD loader does not have the minrev checker anywhere (yet). So, force_minrev is effectively dis_ucode_ldr which may appear excessive. Without enforcement though, it is going to taint the kernel on every early loading then. This side-effect should be reviewed. --- .../admin-guide/kernel-parameters.txt | 4 ++-- arch/x86/Kconfig | 19 +++++++++---------- arch/x86/kernel/cpu/microcode/amd.c | 8 +++++++- arch/x86/kernel/cpu/microcode/core.c | 13 ++++++++++--- arch/x86/kernel/cpu/microcode/intel.c | 17 ++++++++++++----- arch/x86/kernel/cpu/microcode/internal.h | 1 + 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentatio= n/admin-guide/kernel-parameters.txt index cde092017cd8..b5f7a8142f58 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -4073,8 +4073,8 @@ Kernel parameters =20 force_minrev[=3D]: Enable or disable microcode minimal revision enforcement - for the runtime microcode loader according to . If - is not given, enable the enforcement. + for the microcode loader according to . If + is not given, enable the enforcement. =20 mini2440=3D [ARM,HW,KNL] Format:[0..2][b][c][t] diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 15fd9ec5ecac..6c503004775e 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1338,18 +1338,17 @@ config MICROCODE_LATE_LOADING minimal revision check. This minimal revision check can be enforced on the kernel command line with "microcode=3Dforce_minrev". =20 -config MICROCODE_LATE_FORCE_MINREV - bool "Enforce late microcode loading minimal revision check" +config MICROCODE_FORCE_MINREV + bool "Enforce microcode loading minimal revision check" default n - depends on MICROCODE_LATE_LOADING + depends on MICROCODE help - To prevent that users load microcode late which modifies already - in use features, newer microcode patches have a minimum revision field - in the microcode header, which tells the kernel which minimum - revision must be active in the CPU to safely load that new microcode - late into the running system. If disabled the check will not - be enforced but the kernel will be tainted when the minimal - revision check fails. + To prevent that users load microcode which modifies already in use + features, newer microcode patches have a minimum revision field in the + microcode header, which tells the kernel which minimum revision must + be active in the CPU to safely load that new microcode into the system. + If disabled the check will not be enforced but the kernel will be + tainted when the minimal revision check fails. =20 This minimal revision check can also be controlled via the "microcode=3Dforce_minrev" parameter on the kernel command line. diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/micr= ocode/amd.c index 6cdc410e7547..0625d5e8eb7e 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -800,6 +800,11 @@ void __init load_ucode_amd_bsp(struct early_load_data = *ed, unsigned int cpuid_1_ /* Needed in load_microcode_amd() */ ucode_cpu_info[0].cpu_sig.sig =3D cpuid_1_eax; =20 + if (force_minrev) { + pr_warn_once("No early load: minimum revision check is not implemented.\= n"); + return; + } + if (!find_blobs_in_containers(&cp)) return; =20 @@ -1202,7 +1207,8 @@ static int __init save_microcode_in_initrd(void) enum ucode_state ret; struct cpio_data cp; =20 - if (microcode_loader_disabled() || c->x86_vendor !=3D X86_VENDOR_AMD || c= ->x86 < 0x10) + if (microcode_loader_disabled() || c->x86_vendor !=3D X86_VENDOR_AMD || c= ->x86 < 0x10 || + force_minrev) return 0; =20 cpuid_1_eax =3D native_cpuid_eax(1); diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/mic= rocode/core.c index ed1eb6b753d6..7d6caf191795 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -46,7 +46,7 @@ static struct microcode_ops *microcode_ops; static bool dis_ucode_ldr; =20 -bool force_minrev =3D IS_ENABLED(CONFIG_MICROCODE_LATE_FORCE_MINREV); +bool force_minrev =3D IS_ENABLED(CONFIG_MICROCODE_FORCE_MINREV); =20 /* * Those below should be behind CONFIG_MICROCODE_DBG ifdeffery but in @@ -603,7 +603,7 @@ static int load_late_stop_cpus(bool is_safe) =20 if (!is_safe) { pr_err("Late microcode loading without minimal revision check.\n"); - pr_err("You should switch to early loading, if possible.\n"); + pr_err("You should update microcode incrementally.\n"); } =20 /* @@ -912,9 +912,16 @@ static int __init microcode_init(void) =20 pr_info_once("Current revision: 0x%08x\n", (early_data.new_rev ?: early_d= ata.old_rev)); =20 - if (early_data.new_rev) + if (early_data.new_rev) { pr_info_once("Updated early from: 0x%08x\n", early_data.old_rev); =20 + if (!early_data.is_safe) { + pr_err("Early microcode loading without minimal revision check.\n"); + pr_err("You should update microcode incrementally.\n"); + add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK); + } + } + microcode_fdev =3D faux_device_create("microcode", NULL, NULL); if (!microcode_fdev) return -ENODEV; diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/mi= crocode/intel.c index c502138fd8e9..3247c619eaa1 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -786,7 +786,15 @@ void __init load_ucode_intel_bsp(struct early_load_dat= a *ed) uci.mc =3D get_microcode_blob(&uci, false); ed->old_rev =3D uci.cpu_sig.rev; =20 - if (uci.mc && apply_microcode_early(&uci) =3D=3D UCODE_UPDATED) { + if (!uci.mc) + return; + + if (force_minrev) { + pr_warn_once("No early load: minimum revision check is not implemented.\= n"); + return; + } + + if (apply_microcode_early(&uci) =3D=3D UCODE_UPDATED) { ucode_patch_va =3D UCODE_BSP_LOADED; ed->new_rev =3D uci.cpu_sig.rev; } @@ -842,9 +850,8 @@ static bool ucode_validate_minrev(struct microcode_head= er_intel *mc_header) int cur_rev =3D boot_cpu_data.microcode; =20 /* - * When late-loading, ensure the header declares a minimum revision - * required to perform a late-load. The previously reserved field - * is 0 in older microcode blobs. + * Ensure the header declares a minimum revision required to perform a + * load. The previously reserved field is 0 in older microcode blobs. */ if (!mc_header->min_req_ver) { pr_info("Unsafe microcode update: Microcode header does not specify a re= quired min version\n"); @@ -857,7 +864,7 @@ static bool ucode_validate_minrev(struct microcode_head= er_intel *mc_header) */ if (cur_rev < mc_header->min_req_ver) { pr_info("Unsafe microcode update: Current revision 0x%x too old\n", cur_= rev); - pr_info("Current should be at 0x%x or higher. Use early loading instead\= n", mc_header->min_req_ver); + pr_info("Current should be at 0x%x or higher. Update incrementally.\n", = mc_header->min_req_ver); return false; } return true; diff --git a/arch/x86/kernel/cpu/microcode/internal.h b/arch/x86/kernel/cpu= /microcode/internal.h index a10b547eda1e..1b35f9099580 100644 --- a/arch/x86/kernel/cpu/microcode/internal.h +++ b/arch/x86/kernel/cpu/microcode/internal.h @@ -42,6 +42,7 @@ struct microcode_ops { struct early_load_data { u32 old_rev; u32 new_rev; + bool is_safe; }; =20 extern struct early_load_data early_data; --=20 2.53.0 From nobody Sat Sep 26 11:46:59 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BFF16473C65 for ; Tue, 1 Sep 2026 23:43:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306214; cv=none; b=biD8TG3jzLeF3FPZauMHUP7odhCnwMEAw9jNJnS5UUAZzBgQwwGTemfmamCh7+JkbOYZO4tJsOoZYYL7bza3j98hLopHDCLHuLxuBFuSeTpq5Cl1fGoCNxn8oh1Qp8N1McaChaS5KbxQaXK19WyCj7n/VRg1YA5I3BFpoOldUCE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306214; c=relaxed/simple; bh=BsrKqoZGFVI0bb4obu2EyK4rErkmjBzF0gjzDVTq+7I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IMnwoFGfA45OrxmaW6mlRswLOnerXvd8uuHP/Pjsb48Ru7bMaGHx+7xe2SwNwGxWuC2rabRrXDrjWiKLpZZ+vEiPpBVg2EpzI5iadek2d4r4Vr8Ouy4ODzY+DfLEQHxa4mzRNwYc2ugrafJ/vIbeGV5JSjW7CEIGTr37Y5hqzYY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Ss7uhxOR; arc=none smtp.client-ip=192.198.163.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Ss7uhxOR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1788306206; x=1819842206; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=BsrKqoZGFVI0bb4obu2EyK4rErkmjBzF0gjzDVTq+7I=; b=Ss7uhxORPL1m/48QE6RVuWmO4WpuW+T68/BVU7rBu83xO5pFxif7QLPM FLZnYdHoD4CKkgqX35nE5L17VR9NmxFcJ474PIAdS9X6owjTlE7gwt/SG NRkIwWqb4SoWYOTcA55FOkPCozGUrUCDBnBlrEx1gZZ/9cUpLnCvh/UAA /tsWZ6BeOuWo+CTrPMRWYGGUro0g8z/XAw6ce6S2RDWl4uh1rPxPCFcHP RmGXM5yhPlscD3U+uExNE7rnoC5YPE7oS8ggMbeIsGEfOHtyT/J1RoI9Q BRVomHBA+wUYYw9RXy6BiGm8K0npD7mSJR8XTb4bgHIbAsJJZCIJ9hVo/ Q==; X-CSE-ConnectionGUID: JYRBZbxhSJmtrhPotLu+yg== X-CSE-MsgGUID: E1XELeD/QjCSjML4sD5FGQ== X-IronPort-AV: E=McAfee;i="6800,10657,11893"; a="87891903" X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="87891903" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa112.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2026 16:43:25 -0700 X-CSE-ConnectionGUID: yPvqiwIKTtWZ3GGAKmE4FA== X-CSE-MsgGUID: hE1TdyXkQD6OASmdYOzhnw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="267469911" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa006.jf.intel.com with ESMTP; 01 Sep 2026 16:43:25 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, andrew.cooper3@citrix.com, arjan.van.de.ven@intel.com, chang.seok.bae@intel.com Subject: [PATCH RFC 6/8] x86/microcode/intel: Apply minimum revision check to early loading Date: Tue, 1 Sep 2026 23:16:31 +0000 Message-ID: <20260901231634.714144-7-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260901231634.714144-1-chang.seok.bae@intel.com> References: <20260901231634.714144-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The minimum revision check is now generally applicable. Establish the minimum revision check on early loading. Follow the late loading behavior when the check fails: * Load but taint the kernel if not enforced, or * Reject the loading if enforced. Adjust the check function so that the early path can pass the current revision. With this establishment, do not reject early loading anymore when enforced. Suggested-by: Arjan van de Ven Signed-off-by: Chang S. Bae --- arch/x86/kernel/cpu/microcode/intel.c | 64 ++++++++++++--------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/mi= crocode/intel.c index 3247c619eaa1..ddd5b72b27a1 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -341,6 +341,29 @@ static bool is_loading_denied(struct cpu_signature *si= g, u32 rev) return false; } =20 +static bool ucode_validate_minrev(u32 cur_rev, struct microcode_header_int= el *mc_header) +{ + /* + * Ensure the header declares a minimum revision required to perform a + * load. The previously reserved field is 0 in older microcode blobs. + */ + if (!mc_header->min_req_ver) { + pr_info("Unsafe microcode update: Microcode header does not specify a re= quired min version\n"); + return false; + } + + /* + * Check whether the current revision is either greater or equal to + * the minimum revision specified in the header. + */ + if (cur_rev < mc_header->min_req_ver) { + pr_info("Unsafe microcode update: Current revision 0x%x too old.\n", cur= _rev); + pr_info("Current should be at 0x%x or higher. Update incrementally.\n", = mc_header->min_req_ver); + return false; + } + return true; +} + /* Scan blob for microcode matching the boot CPUs family, model, stepping = */ static __init struct microcode_intel *scan_microcode(void *data, size_t si= ze, struct ucode_cpu_info *uci, @@ -365,6 +388,9 @@ static __init struct microcode_intel *scan_microcode(vo= id *data, size_t size, if (is_loading_denied(&uci->cpu_sig, mc_header->rev)) continue; =20 + if (force_minrev && !ucode_validate_minrev(uci->cpu_sig.rev, mc_header)) + continue; + /* * For saving the early microcode, find the matching revision which * was loaded on the BSP. @@ -786,17 +812,10 @@ void __init load_ucode_intel_bsp(struct early_load_da= ta *ed) uci.mc =3D get_microcode_blob(&uci, false); ed->old_rev =3D uci.cpu_sig.rev; =20 - if (!uci.mc) - return; - - if (force_minrev) { - pr_warn_once("No early load: minimum revision check is not implemented.\= n"); - return; - } - - if (apply_microcode_early(&uci) =3D=3D UCODE_UPDATED) { + if (uci.mc && apply_microcode_early(&uci) =3D=3D UCODE_UPDATED) { ucode_patch_va =3D UCODE_BSP_LOADED; ed->new_rev =3D uci.cpu_sig.rev; + ed->is_safe =3D ucode_validate_minrev(ed->old_rev, uci.mc); } } =20 @@ -845,31 +864,6 @@ static enum ucode_state apply_microcode_late(int cpu) return ret; } =20 -static bool ucode_validate_minrev(struct microcode_header_intel *mc_header) -{ - int cur_rev =3D boot_cpu_data.microcode; - - /* - * Ensure the header declares a minimum revision required to perform a - * load. The previously reserved field is 0 in older microcode blobs. - */ - if (!mc_header->min_req_ver) { - pr_info("Unsafe microcode update: Microcode header does not specify a re= quired min version\n"); - return false; - } - - /* - * Check whether the current revision is either greater or equal to - * to the minimum revision specified in the header. - */ - if (cur_rev < mc_header->min_req_ver) { - pr_info("Unsafe microcode update: Current revision 0x%x too old\n", cur_= rev); - pr_info("Current should be at 0x%x or higher. Update incrementally.\n", = mc_header->min_req_ver); - return false; - } - return true; -} - static enum ucode_state parse_microcode_blobs(int cpu, struct iov_iter *it= er) { struct ucode_cpu_info *uci =3D ucode_cpu_info + cpu; @@ -923,7 +917,7 @@ static enum ucode_state parse_microcode_blobs(int cpu, = struct iov_iter *iter) if (is_loading_denied(&uci->cpu_sig, mc_header.rev)) continue; =20 - is_safe =3D ucode_validate_minrev(&mc_header); + is_safe =3D ucode_validate_minrev(uci->cpu_sig.rev, &mc_header); if (force_minrev && !is_safe) continue; =20 --=20 2.53.0 From nobody Sat Sep 26 11:46:59 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7BA3747D443 for ; Tue, 1 Sep 2026 23:43:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306210; cv=none; b=JHcMmsLRvct8xgUmWRDY1rsk4cmpOqzUJevyW0Xf8Xxp1SbgE4g2mvmFnIp+W/3V91xIMAI6QFRgNig8mR2dYQL+Zrti+mEhr6vjYBsRaNI6+MHmJVqaAZGacxgeBultnD68FFmruRATs/0Vqd5m1mSo/BAKG4WE/Dl1oYO2Zhs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306210; c=relaxed/simple; bh=xMVF8li0PUI7fN7jnCZBtwDsj9dwWewU8cRAuFOhIBE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UQ1QRjaU1U9yc9jp67aOGs+8UIaj9Aya/ZBzu0gzsp6kJnKZzDXVMVW2zTb5DKwr2gnvkNJMmbqJGyMKn2C2SL9/0GSMm0XQRq/MVoVq/WMQZNPUa0TFYWXJ57vS9UnpdE1Y19x5hLvZSBtE3/6U+3+YRI1zKjm5mf3+rDAv+C4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=YQs217Re; arc=none smtp.client-ip=192.198.163.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="YQs217Re" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1788306207; x=1819842207; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=xMVF8li0PUI7fN7jnCZBtwDsj9dwWewU8cRAuFOhIBE=; b=YQs217ReQxxBUQ8Jd0claNF+Cz/3qhU1e3qK2Z9yXn/knHD8NU5cf6iY S9mcRgduFl3w8kiln+cAvwgtq5lBDQYR0sht8X+QzAVybKSHfi/gj5HM8 3JS3ehKi/g7WSKvIRnrSEZPGIqdLggb9ueLP3sEQKJN7rtOnnQejIBsBy a4CNbY3PttHsktnCeAhe4TQgsVY1gkObTX8GsPGRRhGCXs0cVFlv37gZW ow56dbBOxUG8wcFzcM7hFuP7PmT23xHCXz2RzTUbxr/fBUHhkm3x82FXY c0x7i+uO06c+VX1+muJ9BB0qIKjIpVFTq/TK810sL0RoZVLfU9l6eBFJn w==; X-CSE-ConnectionGUID: el4ZQPmIS4aO4OEBwoJQmA== X-CSE-MsgGUID: Ccmo7e9hTy6FS81vn+7r8Q== X-IronPort-AV: E=McAfee;i="6800,10657,11893"; a="87891912" X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="87891912" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa112.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2026 16:43:27 -0700 X-CSE-ConnectionGUID: iSudT1M8R9epPpbk+Ff9eg== X-CSE-MsgGUID: ETwsvQ7pQG6heHlo3eCo0w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="267469923" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa006.jf.intel.com with ESMTP; 01 Sep 2026 16:43:27 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, andrew.cooper3@citrix.com, arjan.van.de.ven@intel.com, chang.seok.bae@intel.com Subject: [PATCH RFC 7/8] x86/microcode: Introduce iterative late loading Date: Tue, 1 Sep 2026 23:16:32 +0000 Message-ID: <20260901231634.714144-8-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260901231634.714144-1-chang.seok.bae@intel.com> References: <20260901231634.714144-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The minimum revision requirement was introduced to handle dependencies between microcode revisions. On the other hand, Intel has traditionally distributed only the latest microcode blob in the repository [1]. Instead, to better accommodate those dependent blobs at hand, it is useful to concatenate blobs together into a single image. This allows loading the prerequisite revisions in sequence. The loader currently handles a multi-blob image by selecting the highest revision without minimum revision enforcement. This loading approach may not achieve the safety requirement. If enforced, it skips revisions whose prerequisites have not been loaded, possibly leaving the loading process at an intermediate revision. Then, admins have to manually trigger another load to apply the remaining higher revisions. To avoid this manual step, introduce iterative late loading. After each successful update, let the vendor-specific parser select the next blob. If the parser selects the lowest loadable revision on each pass, the loader can apply the blobs incrementally until no more blobs are available. For now, vendor code rejects this loading because the blob parser is not ready yet to support incremental blob selection. To retain the existing behavior by default, add a Kconfig option and a kernel command-line option to select iterative loading. [1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files.git Signed-off-by: Chang S. Bae --- .../admin-guide/kernel-parameters.txt | 4 ++ arch/x86/Kconfig | 12 +++++ arch/x86/kernel/cpu/microcode/amd.c | 3 +- arch/x86/kernel/cpu/microcode/core.c | 53 +++++++++++++++++-- arch/x86/kernel/cpu/microcode/intel.c | 3 ++ arch/x86/kernel/cpu/microcode/internal.h | 1 + 6 files changed, 72 insertions(+), 4 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentatio= n/admin-guide/kernel-parameters.txt index b5f7a8142f58..67f5b233315f 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -4076,6 +4076,10 @@ Kernel parameters for the microcode loader according to . If is not given, enable the enforcement. =20 + iterative_loading=3D: + Enable or disable iterative microcode patch application + for the runtime microcode loader according to . + mini2440=3D [ARM,HW,KNL] Format:[0..2][b][c][t] Default: "0tb" diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6c503004775e..021c77a6ad4b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1355,6 +1355,18 @@ config MICROCODE_FORCE_MINREV =20 If unsure say Y. =20 +config MICROCODE_LATE_ITERATIVE_LOADING + bool "Iterative microcode late loading" + default n + depends on MICROCODE_LATE_LOADING + help + Apply the microcode blobs in a concatenated image one at a time, in + ascending revision order, so that revisions with prerequisites can be + applied in a single process. + + This loading option can also be controlled via the + "microcode=3Diterative_loading=3D" parameter on the kernel command line. + config MICROCODE_DBG bool "Enable microcode loader debugging" default n diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/micr= ocode/amd.c index 0625d5e8eb7e..97b30da9e5e6 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -1251,7 +1251,8 @@ static enum ucode_state request_microcode_amd(int cpu= , struct device *device) enum ucode_state ret =3D UCODE_NFOUND; const struct firmware *fw; =20 - if (force_minrev) + /* The blob parser does not support these features yet. */ + if (force_minrev || iterative_loading) return UCODE_NFOUND; =20 if (c->x86 >=3D 0x15) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/mic= rocode/core.c index 7d6caf191795..e7e159479975 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -47,6 +47,7 @@ static struct microcode_ops *microcode_ops; static bool dis_ucode_ldr; =20 bool force_minrev =3D IS_ENABLED(CONFIG_MICROCODE_FORCE_MINREV); +bool iterative_loading =3D IS_ENABLED(CONFIG_MICROCODE_LATE_ITERATIVE_LOAD= ING); =20 /* * Those below should be behind CONFIG_MICROCODE_DBG ifdeffery but in @@ -166,6 +167,12 @@ static void __init early_parse_cmdline(void) continue; } =20 + if (str_has_prefix(s, "iterative_loading=3D")) { + advance_option_argument(&s); + if (kstrtobool(s, &iterative_loading)) { ; } + continue; + } + if (!strcmp(s, "dis_ucode_ldr")) dis_ucode_ldr =3D true; } @@ -750,16 +757,34 @@ static bool setup_cpus(void) return true; } =20 +static void reset_ucode_ctrl(void) +{ + struct microcode_ctrl ctrl =3D { .ctrl =3D SCTRL_WAIT, .result =3D -1, }; + unsigned int cpu; + + for_each_cpu_and(cpu, cpu_present_mask, &cpus_booted_once_mask) { + ctrl.ctrl_cpu =3D per_cpu(ucode_ctrl.ctrl_cpu, cpu); + per_cpu(ucode_ctrl, cpu) =3D ctrl; + } +} + static int load_late_locked(void) { + enum ucode_state state; + int err; + if (!setup_cpus()) return -EBUSY; =20 - switch (microcode_ops->request_microcode_fw(0, µcode_fdev->dev)) { + state =3D microcode_ops->request_microcode_fw(0, µcode_fdev->dev); +next: + switch (state) { case UCODE_NEW: - return load_late_stop_cpus(false); + err =3D load_late_stop_cpus(false); + break; case UCODE_NEW_SAFE: - return load_late_stop_cpus(true); + err =3D load_late_stop_cpus(true); + break; case UCODE_NFOUND: return -ENOENT; case UCODE_OK: @@ -767,6 +792,28 @@ static int load_late_locked(void) default: return -EBADFD; } + + if (err) + return err; + + /* + * A multi-blob image is traditionally handled by selecting the highest + * revision to load it in one shot. With iterative loading, the + * vendor-specific parser instead selects the lowest loadable revision. + * + * After each successful update, find the next loadable blob to continue + * the iteration. Stop if no more blobs are found. + */ + if (iterative_loading) { + state =3D microcode_ops->request_microcode_fw(0, µcode_fdev->dev); + if (state =3D=3D UCODE_NFOUND) + return 0; + + reset_ucode_ctrl(); + goto next; + } + + return 0; } =20 static ssize_t reload_store(struct device *dev, diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/mi= crocode/intel.c index ddd5b72b27a1..48e7d023ea41 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -978,6 +978,9 @@ static enum ucode_state request_microcode_fw(int cpu, s= truct device *device) if (is_late_loading_denied(cpu)) return UCODE_NFOUND; =20 + if (iterative_loading) + return UCODE_NFOUND; + sprintf(name, "intel-ucode/%02x-%02x-%02x", c->x86, c->x86_model, c->x86_stepping); =20 diff --git a/arch/x86/kernel/cpu/microcode/internal.h b/arch/x86/kernel/cpu= /microcode/internal.h index 1b35f9099580..311e885819a2 100644 --- a/arch/x86/kernel/cpu/microcode/internal.h +++ b/arch/x86/kernel/cpu/microcode/internal.h @@ -101,6 +101,7 @@ static inline unsigned int x86_cpuid_family(void) } =20 extern bool force_minrev; +extern bool iterative_loading; =20 #ifdef CONFIG_CPU_SUP_AMD void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family); --=20 2.53.0 From nobody Sat Sep 26 11:46:59 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DBA7949B1F4 for ; Tue, 1 Sep 2026 23:43:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306210; cv=none; b=BJJ/dh7x34ajpq4Qr3NO6c6RJrLMVIEPLYVWuNgcYVOrOFlpkm8zaRdr+E6eQsRF5LjkdCKOlPN5SdfNhUzKWFTFkZRewE2QLidGGcZVLfAB6p5RQX9CmZJcUqCh53GPRf/Yo1vTIJsjGYMBJtIWdf0SXmAmAJhZy1kW6gL2Uhw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788306210; c=relaxed/simple; bh=ntouSyFznmv8TJgRxbpHSz6u7LixB3//ApXqB29BbNQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SjgmKlJ9taKLxSixR8C1/bNDju+q0emzGbSjzPL3IO648m61lm+ZsQK0ALLSdn/hP7U0Jc67aHUkUlSkt4y6stPuKAbDVqykaFZLviLQb6UDkXFS9PI7sRacb4rab/gLJNq95R7PTUooipeFnfRgtKW+l7W+KH4dtQARAdeQ9TQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Mu2xmzUh; arc=none smtp.client-ip=192.198.163.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Mu2xmzUh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1788306209; x=1819842209; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ntouSyFznmv8TJgRxbpHSz6u7LixB3//ApXqB29BbNQ=; b=Mu2xmzUh7w6U1ZAUNMWk3dMhj4/5VvT6S1EJEtNj7Kqm8re2U8GBxudw CI+9rytZtUy5K1NdOgsT38KxyStoj6r7m9mEPkc0UAvctbdPGdMS5Zrwo /1FgneQhYY4wXdB6FBp8Am6Zd6v/72yjiNneHVMqHGXNJ5MN45XAj1Fgz PueWz7M7jH8Y4xuLY3+d0vrkXRBVp0LTsmmIYRzod6y8X2EJ3ML+336yi lLV2tAFV8Q7BO8P7QGs8UAzoodbWd695sKzpr6ICy9nKCqCYFbWAGTEzJ 4VB+olVHDbjiBn8eTQ6heiW705CRIubhACvjx5vk3j7vQvQwaMbDO3F/l w==; X-CSE-ConnectionGUID: mYoW2+CDQ5yNhXTSLlXvEA== X-CSE-MsgGUID: MF3kekZ1S5GZ3tHpQC75mQ== X-IronPort-AV: E=McAfee;i="6800,10657,11893"; a="87891920" X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="87891920" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa112.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2026 16:43:28 -0700 X-CSE-ConnectionGUID: V7TS83dJTEChtjtpWZCgvQ== X-CSE-MsgGUID: VE3GLKq/SA6jE3q1jjTWIg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,256,1779174000"; d="scan'208";a="267469929" Received: from chang-linux-3.sc.intel.com (HELO chang-linux-3) ([172.25.66.174]) by orviesa006.jf.intel.com with ESMTP; 01 Sep 2026 16:43:28 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, andrew.cooper3@citrix.com, arjan.van.de.ven@intel.com, chang.seok.bae@intel.com Subject: [PATCH RFC 8/8] x86/microcode/intel: Select the lowest loadable revision for iterative loading Date: Tue, 1 Sep 2026 23:16:33 +0000 Message-ID: <20260901231634.714144-9-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260901231634.714144-1-chang.seok.bae@intel.com> References: <20260901231634.714144-1-chang.seok.bae@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The iterative loading logic in the core can repeatedly request a microcode patch. The vendor parser currently selects the highest loadable revision, which means no further patch can be selected after the first update. To load a concatenated multi-blob image incrementally, adjust the blob parser to select the lowest loadable revision. This allows patches to be applied in ascending revision order. Signed-off-by: Chang S. Bae --- arch/x86/kernel/cpu/microcode/intel.c | 34 ++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/mi= crocode/intel.c index 48e7d023ea41..3a699e361fe0 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -864,14 +864,39 @@ static enum ucode_state apply_microcode_late(int cpu) return ret; } =20 +static bool is_revision_candidate(unsigned int cur_rev, unsigned int rev) +{ + /* + * A revision must be newer than the active microcode revision to be + * loadable. + */ + if (rev <=3D boot_cpu_data.microcode) + return false; + + /* + * Iterative loading selects the lowest loadable revision so that + * revisions can be applied incrementally. + */ + if (iterative_loading) + return rev < cur_rev; + + /* Legacy late loading selects the highest loadable revision. */ + return rev > cur_rev; +} + static enum ucode_state parse_microcode_blobs(int cpu, struct iov_iter *it= er) { struct ucode_cpu_info *uci =3D ucode_cpu_info + cpu; + unsigned int cur_rev, curr_mc_size =3D 0; bool is_safe, new_is_safe =3D false; - int cur_rev =3D uci->cpu_sig.rev; - unsigned int curr_mc_size =3D 0; u8 *new_mc =3D NULL, *mc =3D NULL; =20 + /* + * Start from the boundary value for the revision search. With iterative + * loading search walks downward but the legacy search walks upward. + */ + cur_rev =3D iterative_loading ? UINT_MAX : 0; + while (iov_iter_count(iter)) { struct microcode_header_intel mc_header; unsigned int mc_size, data_size; @@ -908,7 +933,7 @@ static enum ucode_state parse_microcode_blobs(int cpu, = struct iov_iter *iter) intel_microcode_sanity_check(mc, true, MC_HEADER_TYPE_MICROCODE) < 0) goto fail; =20 - if (cur_rev >=3D mc_header.rev) + if (!is_revision_candidate(cur_rev, mc_header.rev)) continue; =20 if (!intel_find_matching_signature(mc, &uci->cpu_sig)) @@ -978,9 +1003,6 @@ static enum ucode_state request_microcode_fw(int cpu, = struct device *device) if (is_late_loading_denied(cpu)) return UCODE_NFOUND; =20 - if (iterative_loading) - return UCODE_NFOUND; - sprintf(name, "intel-ucode/%02x-%02x-%02x", c->x86, c->x86_model, c->x86_stepping); =20 --=20 2.53.0