MAINTAINERS | 1 + scripts/update-intel-ucode-defs.py | 118 +++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100755 scripts/update-intel-ucode-defs.py
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 <dave.hansen@linux.intel.com>
Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
---
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
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..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 = 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 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 = argparse.ArgumentParser(description=DESCRIPTION,
+ formatter_class=argparse.RawDescriptionHelpFormatter)
+parser.add_argument('ucode_files', nargs='+', help='Path(s) to the microcode files')
+
+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", file=sys.stderr)
+ sys.exit(1)
+
+cmd = ['iucode-tool', '--list-all' ]
+cmd.extend(args.ucode_files)
+
+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", file=sys.stderr)
+ 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", file=sys.stderr)
+ 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 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", file=sys.stderr)
+ sys.exit(1)
+
+# Sort and print the microcode entries
+ucode_entries.sort(key=lambda x: (x['family'], x['model'], x['steppings']))
+for entry in ucode_entries:
+ print("{ .flags = X86_CPU_ID_FLAG_ENTRY_VALID, .vendor = X86_VENDOR_INTEL, .family = 0x%x, .model = 0x%02x, .steppings = 0x%04x, .driver_data = 0x%x }," %
+ (entry['family'], entry['model'], entry['steppings'], entry['rev']))
--
2.43.0
On Thu, Aug 21, 2025 at 05:44:22PM -0700, Sohil Mehta wrote: > 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. I can see the "what" - you don't have to explain it. What I don't see in this commit message is the "why". Why should this be in the kernel? -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette
On 8/22/2025 3:09 AM, Borislav Petkov wrote: > What I don't see in this commit message is the "why". Why should > this be in the kernel? > Currently, we have a static list of microcode revisions that determine old_microcode. So, it needs to be periodically updated as and when new microcode releases are made. Also, some folks might want to have a custom enforcement of the minimum microcode revisions (be it stricter or relaxed). The script makes it easier to update intel-ucode-defs.h by generating output in the specific format it needs. Having this live in the kernel makes it easier to find whenever needed and also be in sync with the header format if it ever changes. If you agree, I can update the commit message to include the why.
On Fri, Aug 22, 2025 at 11:03:10AM -0700, Sohil Mehta wrote: > Currently, we have a static list of microcode revisions that determine > old_microcode. So, it needs to be periodically updated as and when new > microcode releases are made. Who is expected to do that and when? > Also, some folks might want to have a custom enforcement of the minimum > microcode revisions (be it stricter or relaxed). I don't understand how that relates to the script. > The script makes it easier to update intel-ucode-defs.h by generating > output in the specific format it needs. Having this live in the kernel > makes it easier to find whenever needed What?! -ENOPARSE. > and also be in sync with the header format if it ever changes. I have a big problem with people being able to willy-nilly update this header and then things starting to fail because someone updated the header but it was wrong and then we have to go debug that too. Update to the header needs to happen in very controlled manner, when you have released tested microcode and have decided to deprecate old microcode. Not just lightheartedly shoot out a new header version out because shit got updated somewhere. So, actually, this script should NOT be in the kernel but in some repo internal in Intel. -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette
On 8/22/25 11:24, Borislav Petkov wrote: > Update to the header needs to happen in very controlled manner, when you have > released tested microcode and have decided to deprecate old microcode. Right. It'll happen in response to a public microcode release. > So, actually, this script should NOT be in the kernel but in some repo > internal in Intel. We could definitely put it there. But it's generating a 100% Linux-specific header that nobody else can use. So it's really a purely Linux thing. Not really a great fit for what is otherwise just a microcode repository. I honestly don't care that much if it's in the kernel tree or not. The best part for me of having it in the kernel is that it makes it easier for _anybody_ to just go make a patch to update the header when I'm too lazy to do it. I'll probably just go stick it in some other kernel.org repo if folks don't want it upstream.
On Fri, Aug 22, 2025 at 11:31:40AM -0700, Dave Hansen wrote: > We could definitely put it there. But it's generating a 100% > Linux-specific header that nobody else can use. So it's really a purely > Linux thing. Not really a great fit for what is otherwise just a > microcode repository. Just to clarify again: I don't care if it is in the kernel as long as there's a clear policy when those files are updated and also specified that any update is sanctioned by you guys since doing a public microcode release kinda says that what you're releasing is verified and tested and the stuff you're deprecating can be deprecated. What I don't want to have is some random people running this because they saw some microcode on github which someone carved out from BIOS and claims now that this is valid microcode. Or some other funky thing... And I don't think you want to be in such a situation either. So as long as it unmistakenly specifies who updates the header, the script can be anywhere. I hope I'm making more sense. Thx. -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette
On 8/22/25 12:06, Borislav Petkov wrote: > So as long as it unmistakenly specifies who updates the header, the script can > be anywhere. > > I hope I'm making more sense. Ahh, gotcha. Should we slap something like this in the script? This script is intended to be run in response to releases of the official Intel microcode github repository[link]. 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.
On Fri, Aug 22, 2025 at 12:16:59PM -0700, Dave Hansen wrote: > Ahh, gotcha. Should we slap something like this in the script? > > This script is intended to be run in response to releases of the > official Intel microcode github repository[link]. 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. Yap, thanks! -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette
On 8/22/2025 12:27 PM, Borislav Petkov wrote: > On Fri, Aug 22, 2025 at 12:16:59PM -0700, Dave Hansen wrote: >> Ahh, gotcha. Should we slap something like this in the script? >> >> This script is intended to be run in response to releases of the >> official Intel microcode github repository[link]. 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. > > Yap, thanks! > Thanks! Here is the updated help description in the script: DESCRIPTION = 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. """ If there are no other comments, I'll send out a revised version with an updated commit message early next week.
© 2016 - 2025 Red Hat, Inc.