mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Sohil Mehta <sohil.mehta@intel.com>
To: Dave Hansen <dave.hansen@linux.intel.com>, x86@kernel.org
Cc: Borislav Petkov <bp@alien8.de>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "H . Peter Anvin" <hpa@zytor.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Josh Poimboeuf <jpoimboe@kernel.org>,
	Pawan Gupta <pawan.kumar.gupta@linux.intel.com>,
	Dave Hansen <dave.hansen@intel.com>,
	Nikolay Borisov <nik.borisov@suse.com>,
	Alex Murray <alex.murray@canonical.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	Sohil Mehta <sohil.mehta@intel.com>,
	linux-kernel@vger.kernel.org
Subject: [PATCH 2/2] scripts/x86: Add a script to update minimum Intel ucode revisions
Date: Mon, 18 Aug 2025 12:01:37 -0700	[thread overview]
Message-ID: <20250818190137.3525414-3-sohil.mehta@intel.com> (raw)
In-Reply-To: <20250818190137.3525414-1-sohil.mehta@intel.com>

The kernel keeps a table of the minimum expected microcode revisions for
Intel CPUs at intel-ucode-defs.h. Systems with microcode older those are
marked with X86_BUG_OLD_MICROCODE. For more details, see
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 <dave.hansen@linux.intel.com>
Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
---
 MAINTAINERS                        |   1 +
 scripts/update-intel-ucode-defs.py | 134 +++++++++++++++++++++++++++++
 2 files changed, 135 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
 
 X86 MCE INFRASTRUCTURE
 M:	Tony Luck <tony.luck@intel.com>
diff --git a/scripts/update-intel-ucode-defs.py b/scripts/update-intel-ucode-defs.py
new file mode 100755
index 000000000000..b8248f023cce
--- /dev/null
+++ b/scripts/update-intel-ucode-defs.py
@@ -0,0 +1,134 @@
+#!/usr/bin/python3
+# SPDX-License-Identifier: GPL-2.0
+import argparse
+import re
+import shutil
+import subprocess
+import sys
+import os
+
+script = os.path.relpath(__file__)
+
+DESCRIPTION = 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 formats the output
+and writes it to intel-ucode-defs.h which holds the minimum expected
+revision for each family-model-stepping.
+
+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} -u /path/to/microcode/files
+
+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.
+"""
+
+# Get the path to the microcode header defines
+script_path = os.path.abspath(sys.argv[0])
+linux_root = os.path.dirname(os.path.dirname(script_path))
+ucode_hdr = os.path.join(linux_root, 'arch/x86/kernel/cpu/microcode/intel-ucode-defs.h')
+
+parser = argparse.ArgumentParser(description=DESCRIPTION,
+                                 formatter_class=argparse.RawDescriptionHelpFormatter)
+parser.add_argument('-u','--ucode_path', required=True,
+                    help='Path to the microcode files')
+parser.add_argument('-o','--output', dest='header', default=ucode_hdr,
+                    help='The microcode header file to be updated (default: intel-ucode-defs.h)')
+
+args = 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")
+    sys.exit(1)
+
+cmd = ['iucode-tool', '--list-all' ]
+cmd.append(args.ucode_path)
+
+process = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)
+process.wait()
+if process.returncode != 0:
+    print("Error: iucode-tool ran into an error, exiting")
+    sys.exit(1)
+
+# Functions to extract family, model, and stepping
+def bits(val, bottom, top):
+    mask = (1 << (top + 1 - bottom)) - 1
+    mask = mask << bottom
+    return (val & mask) >> bottom
+
+def family(sig):
+    if bits(sig, 8, 11) == 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 = []
+for line in process.stdout:
+    if line.find(" sig ") == -1:
+        continue
+    sig = re.search('sig (0x[0-9a-fA-F]+)', line).group(1)
+    rev = re.search('rev (0x[0-9a-fA-F]+)', line).group(1)
+    sig = int(sig, 16)
+    rev = int(rev, 16)
+    debug_rev = bits(rev, 31, 31)
+    if debug_rev != 0:
+        print("Error: Debug ucode file found, exiting")
+        sys.exit(1);
+
+    sigrev = {}
+    sigrev['sig'] = sig
+    sigrev['rev'] = rev
+    siglist = siglist + [ sigrev ]
+
+# Remove duplicates, if any
+sigdict = {}
+for sr in siglist:
+    existing = sigdict.get(sr['sig'])
+    if existing != None:
+        # If the existing one is newer, just move on:
+        if existing['rev'] > sr['rev']:
+            continue
+    sigdict[sr['sig']] = sr
+
+# Prepare and sort the microcode entries
+ucode_entries = []
+for sig in sigdict:
+    rev = 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")
+    sys.exit(1)
+
+ucode_entries.sort(key=lambda x: (x['family'], x['model'], x['steppings']))
+
+# Update the microcode header file
+header_path = args.header
+if not os.path.exists(header_path):
+    print(f"Error: '{header_path}' does not exist, use the '-o' option to specify a file to update")
+    sys.exit(1)
+
+with open(header_path, "w") as f:
+    for entry in ucode_entries:
+        f.write("{ .flags = X86_CPU_ID_FLAG_ENTRY_VALID, .vendor = X86_VENDOR_INTEL, .family = 0x%x,  .model = 0x%02x, .steppings = 0x%04x, .driver_data = 0x%x },\n" %
+                (entry['family'], entry['model'], entry['steppings'], entry['rev']))
-- 
2.43.0


  parent reply	other threads:[~2025-08-18 19:03 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-18 19:01 [PATCH 0/2] x86/intel: Refresh the old ucode revisions with a script Sohil Mehta
2025-08-18 19:01 ` [PATCH 1/2] x86/microcode/intel: Refresh the revisions that determine old_microcode Sohil Mehta
2025-08-19  5:19   ` Pawan Gupta
2025-08-19 11:18     ` Andrew Cooper
2025-08-19 16:13       ` Sohil Mehta
2025-08-19 18:31         ` Pawan Gupta
2025-08-19 18:28       ` Pawan Gupta
2025-08-19 19:07         ` Dave Hansen
2025-08-19 20:21           ` Andrew Cooper
2025-10-22 17:14   ` Old microcode CPU matching issue - " Jon Kohler
2025-10-22 17:53     ` Dave Hansen
2025-11-14 20:34       ` Dave Hansen
2025-11-20 16:35         ` Jon Kohler
2025-11-20 17:29           ` Sohil Mehta
2025-11-20 19:13             ` Sohil Mehta
2025-11-20 19:27               ` Dave Hansen
2025-11-21  0:39                 ` Dave Hansen
2025-11-21 20:26                   ` Sohil Mehta
2025-11-26  3:00                   ` Jon Kohler
2025-08-18 19:01 ` Sohil Mehta [this message]
2025-08-19 17:14   ` [PATCH 2/2] scripts/x86: Add a script to update minimum Intel ucode revisions Dave Hansen
2025-08-19 20:41     ` Sohil Mehta

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250818190137.3525414-3-sohil.mehta@intel.com \
    --to=sohil.mehta@intel.com \
    --cc=alex.murray@canonical.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=jpoimboe@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=nik.borisov@suse.com \
    --cc=pawan.kumar.gupta@linux.intel.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®