From nobody Fri Oct 3 20:26:56 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.10]) (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 03F2B191F72 for ; Mon, 25 Aug 2025 17:17:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756142226; cv=none; b=BzoVh2tiTrocie7fQpMGIVNaSGWvYEliDNE2YI9wOG8loP1hZCCjNFpvvbEhzuls66RaxX37SpRu6JCzV9Un0xGzndKKNHoxbC6CF4sq/F8Fw29G2PaTq+rgM8Tz+KdjIn6MtiAT+cf2MDSFUVE6V/sXtQwp5Omu9HYRkYMQ9gY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756142226; c=relaxed/simple; bh=NMkfxo5MQkD4PnFu+/zJpUR7eCzzYYERGDUwOfhnTaM=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=GYI7aoHgJ9g1jU+lcuCN0bQ+XLw7TMjZfpHrSRBQ0DWmV32WFQnRhqAxT1HmTQSVG4LUPbrcVudsibpy4ziYYB/TzcQXQ9PbtCRX9ulyMaby7+XvawNfz1clXENF7Nnpd3cbduzQVuk7NUh4SZTwdgWL/cq8gv904pRX7pZa3cI= 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=X3RDjmrg; arc=none smtp.client-ip=192.198.163.10 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="X3RDjmrg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1756142224; x=1787678224; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=NMkfxo5MQkD4PnFu+/zJpUR7eCzzYYERGDUwOfhnTaM=; b=X3RDjmrg/dsludx013TdH4x5Q2iFbDP/Log8ULxtqrQ8FtQJ09XT2GCW IrI0JIKHEhXtsfffgNDqAlmblxRjfdEL+NSXHSzvGKNNtzkwvExvA6cyR gS12cORkTXR2hZMfoR/dgEtXK8E6JNIw0AtqxuPM45lcx/zlRH8GoKNZh OolEkSl5ASc42/aX1BaPHKnnII+p47dHYlQW6K4wT6w+6DvaJI8N97Ef7 w5p3hBwqPaCAaEnOYEMjGV8e2wBaNJmXvvjBXZUBSfLpUJgtZdAIOPI/g 6QCHNIZCb4HxqzOGj0H6ECHoRqIMQW9nU7pDiT9edKb9SLh1tHoY4SVp8 Q==; X-CSE-ConnectionGUID: IyDARp+bRpSh4r6KOm2DDw== X-CSE-MsgGUID: 1oMcafGaTmeNVZ5IXZL0rA== X-IronPort-AV: E=McAfee;i="6800,10657,11533"; a="69735750" X-IronPort-AV: E=Sophos;i="6.18,213,1751266800"; d="scan'208";a="69735750" Received: from orviesa004.jf.intel.com ([10.64.159.144]) by fmvoesa104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Aug 2025 10:17:03 -0700 X-CSE-ConnectionGUID: XDF08hV4TM+LVIBNa6ORTg== X-CSE-MsgGUID: wXiPNtoCQJ+JGN/sXqORKA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,213,1751266800"; d="scan'208";a="173748564" Received: from sohilmeh.sc.intel.com ([172.25.103.65]) by orviesa004.jf.intel.com with ESMTP; 25 Aug 2025 10:17:02 -0700 From: Sohil Mehta To: Dave Hansen , Borislav Petkov , x86@kernel.org Cc: Thomas Gleixner , Ingo Molnar , "H . Peter Anvin" , Peter Zijlstra , Josh Poimboeuf , Pawan Gupta , Dave Hansen , Nikolay Borisov , Andrew Cooper , Sohil Mehta , linux-kernel@vger.kernel.org Subject: [PATCH v3] scripts/x86/intel: Add a script to update the minimum ucode revisions Date: Mon, 25 Aug 2025 10:15:10 -0700 Message-ID: <20250825171510.3332029-1-sohil.mehta@intel.com> X-Mailer: git-send-email 2.43.0 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 kernel maintains a table of minimum expected microcode revisions for Intel CPUs in intel-ucode-defs.h. Systems with microcode older than these revisions are flagged with X86_BUG_OLD_MICROCODE. The static list of microcode revisions needs to be updated periodically in response to releases of the official microcode at: https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files.git. Introduce a simple script to extract the revision information from the microcode files and print it in the precise format expected by the microcode header. Having the script in the kernel mainly makes it easier to update the header whenever needed. Typically, someone at Intel would see a new public release, run this script, refresh the intel-ucode-defs.h file and send a patch upstream to update the mainline and stable versions. Originally-by: Dave Hansen Signed-off-by: Sohil Mehta --- v3: - Include motivation for having the script in the kernel. (Boris) - Update instructions to clarify typical usage. (Boris) v2: https://lore.kernel.org/lkml/20250822004422.2908427-1-sohil.mehta@intel= .com/ - Remove the extra command line arguments. (DaveH) - Print to stdout instead of directly updating the header file. (DaveH) - Take multiple directories as input. (DaveH) --- MAINTAINERS | 1 + scripts/update-intel-ucode-defs.py | 118 +++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100755 scripts/update-intel-ucode-defs.py diff --git a/MAINTAINERS b/MAINTAINERS index daf520a13bdf..a819559ec672 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -27260,6 +27260,7 @@ S: Maintained F: Documentation/admin-guide/hw-vuln/ F: arch/x86/include/asm/nospec-branch.h F: arch/x86/kernel/cpu/bugs.c +F: scripts/update-intel-ucode-defs.py =20 X86 MCE INFRASTRUCTURE M: Tony Luck diff --git a/scripts/update-intel-ucode-defs.py b/scripts/update-intel-ucod= e-defs.py new file mode 100755 index 000000000000..14954e5e33c2 --- /dev/null +++ b/scripts/update-intel-ucode-defs.py @@ -0,0 +1,118 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0 +import argparse +import re +import shutil +import subprocess +import sys +import os + +script =3D os.path.relpath(__file__) + +DESCRIPTION =3D f""" +For Intel CPUs, update the microcode revisions that determine +X86_BUG_OLD_MICROCODE. + +This script is intended to be run in response to releases of the +official Intel microcode GitHub repository: +https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files.git + +It takes the Intel microcode files as input and uses iucode-tool to +extract the revision information. It prints the output in the format +expected by intel-ucode-defs.h. + +Usage: + ./{script} /path/to/microcode/files > /path/to/intel-ucode-defs.h + +Typically, someone at Intel would see a new release, run this script, +refresh the intel-ucode-defs.h file, and send a patch upstream to update +the mainline and stable versions. +""" + +parser =3D argparse.ArgumentParser(description=3DDESCRIPTION, + formatter_class=3Dargparse.RawDescription= HelpFormatter) +parser.add_argument('ucode_files', nargs=3D'+', help=3D'Path(s) to the mic= rocode files') + +args =3D parser.parse_args() + +# Process the microcode files using iucode-tool +if shutil.which("iucode-tool") is None: + print("Error: iucode-tool not found, please install it", file=3Dsys.st= derr) + sys.exit(1) + +cmd =3D ['iucode-tool', '--list-all' ] +cmd.extend(args.ucode_files) + +process =3D subprocess.Popen(cmd, stdout=3Dsubprocess.PIPE, universal_newl= ines=3DTrue) +process.wait() +if process.returncode !=3D 0: + print("Error: iucode-tool ran into an error, exiting", file=3Dsys.stde= rr) + sys.exit(1) + +# Functions to extract family, model, and stepping +def bits(val, bottom, top): + mask =3D (1 << (top + 1 - bottom)) - 1 + mask =3D mask << bottom + return (val & mask) >> bottom + +def family(sig): + if bits(sig, 8, 11) =3D=3D 0xf: + return bits(sig, 8, 11) + bits(sig, 20, 27) + return bits(sig, 8, 11) + +def model(sig): + return bits(sig, 4, 7) | (bits(sig, 16, 19) << 4) + +def step(sig): + return bits(sig, 0, 3) + +# Parse the output of iucode-tool +siglist =3D [] +for line in process.stdout: + if line.find(" sig ") =3D=3D -1: + continue + sig =3D re.search('sig (0x[0-9a-fA-F]+)', line).group(1) + rev =3D re.search('rev (0x[0-9a-fA-F]+)', line).group(1) + sig =3D int(sig, 16) + rev =3D int(rev, 16) + debug_rev =3D bits(rev, 31, 31) + if debug_rev !=3D 0: + print("Error: Debug ucode file found, exiting", file=3Dsys.stderr) + sys.exit(1); + + sigrev =3D {} + sigrev['sig'] =3D sig + sigrev['rev'] =3D rev + siglist =3D siglist + [ sigrev ] + +# Remove duplicates, if any +sigdict =3D {} +for sr in siglist: + existing =3D sigdict.get(sr['sig']) + if existing !=3D None: + # If the existing one is newer, just move on: + if existing['rev'] > sr['rev']: + continue + sigdict[sr['sig']] =3D sr + +# Prepare the microcode entries +ucode_entries =3D [] +for sig in sigdict: + rev =3D sigdict[sig] + ucode_entries.append({ + 'family': family(sig), + 'model': model(sig), + 'steppings': 1 << step(sig), + 'rev': rev['rev'], + 'sig': sig + }) + +if not ucode_entries: + print("Error: No valid microcode files found, exiting", file=3Dsys.std= err) + sys.exit(1) + +# Sort and print the microcode entries +ucode_entries.sort(key=3Dlambda x: (x['family'], x['model'], x['steppings'= ])) +for entry in ucode_entries: + print("{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDO= R_INTEL, .family =3D 0x%x, .model =3D 0x%02x, .steppings =3D 0x%04x, .driv= er_data =3D 0x%x }," % + (entry['family'], entry['model'], entry['steppings'], entry['rev= '])) --=20 2.43.0