From nobody Sat Oct 4 00:28:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.15]) (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 B1588139E for ; Fri, 22 Aug 2025 00:46:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755823587; cv=none; b=u0IBPYjvN2LO/KvA56zlkVv268HUAbYF3QUkB/xwNTK9puc8cFjum6Q+LZnBdkgist0xNyMu03gHswpTivVnawkxe0onERInNnW/ha0a3crFd5UFFspn6wfQmgbETdtUUrq0SZIRmvBz3AWEPnSC9BkxwLgCQ8jNYHZ4vkGqS/o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755823587; c=relaxed/simple; bh=AyuZ+POIzx5Uu2DT9J+ItP+lp/B8Uaqi05bxyQMe+AI=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=XWSrfHre7UD70ZzRDPM5A72DySAammxTLNjLOiigyi1/K6DW0dUBdfbqW5Fh9HIwN4ZZ1gmLx/sQHpS6Sov+CB+YI+N4qon+TShKjaJik16btB1rAITt0c1W+K2t6E3J9pem0bc4bTR9qM2GkpV3EqetD2xNZ/XMB2FBdCekbew= 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=arjedX3X; arc=none smtp.client-ip=198.175.65.15 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="arjedX3X" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1755823585; x=1787359585; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=AyuZ+POIzx5Uu2DT9J+ItP+lp/B8Uaqi05bxyQMe+AI=; b=arjedX3XlpKgMqHrT5o/NtH+Y7Gpjnhc2fkZqYHoHbhtAg+LQVXfwNIm b59qMQNzC2/4nrdGeHsBLVmQmuSlyUpbIlidwuLUNSUdNG3Ic7x4WfJQZ nj13Cpd+Fj1hDkbRZuhfG1Afed7QqbOnyycBU1REuihzdxdtml16RPmxR K3PY4gV03TxgXrNXU48PwIHB8n51WeBf1UEFjoNAvaH+dB+DxfubKTTfO oWavTYBJu0+m/r2DIywDU55X9UYx8n0qqdLdp4ZRWtV6Jc9yn9EruOzIh 4SQ10YgU7aH91v0/CzNoEJIFEFbi4htmqQyBly7lPFOopfvvC2xkouOFu Q==; X-CSE-ConnectionGUID: HhkpXNapSdS60ruVdLjU0g== X-CSE-MsgGUID: LAVhwp4oSzeaDxR1tbfCJw== X-IronPort-AV: E=McAfee;i="6800,10657,11529"; a="61773543" X-IronPort-AV: E=Sophos;i="6.17,309,1747724400"; d="scan'208";a="61773543" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by orvoesa107.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Aug 2025 17:46:25 -0700 X-CSE-ConnectionGUID: bY5Xa+bmRh6XLRPPSNYYOw== X-CSE-MsgGUID: lAZqqa/wRHOZ1mCJZEhtKQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.17,309,1747724400"; d="scan'208";a="172757255" Received: from sohilmeh.sc.intel.com ([172.25.103.65]) by orviesa003.jf.intel.com with ESMTP; 21 Aug 2025 17:46:25 -0700 From: Sohil Mehta To: Dave Hansen , x86@kernel.org Cc: Borislav Petkov , 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 v2] scripts/x86/intel: Add a script to update the minimum ucode revisions Date: Thu, 21 Aug 2025 17:44:22 -0700 Message-ID: <20250822004422.2908427-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. For more details, refer to Documentation/admin-guide/hw-vuln/old_microcode.rst. Add a simple script to keep the header file up-to-date based on released microcode updates. Originally-by: Dave Hansen Signed-off-by: Sohil Mehta --- v2: - Remove the extra command line arguments. - Print to stdout instead of directly updating the header file. - Take multiple directories as input. v1: https://lore.kernel.org/lkml/20250818190137.3525414-1-sohil.mehta@intel= .com/ --- 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..96e91640033a --- /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. + +The script takes the Intel microcode files as input and uses the +iucode-tool to extract the revision information. It prints the output in +the format expected by intel-ucode-defs.h. + +A typical usage is to get the desired release of the Intel Microcode +Update Package at: +https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files.git + +And run: + ./{script} /path/to/microcode/files > /path/to/intel-ucode-defs.h + +Note: The microcode revisions are usually updated shortly after a new +microcode package is released, allowing a reasonable time for systems to +get the update. +""" + +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