CHANGELOG.md | 1 + docs/misc/xen-command-line.pandoc | 19 ++++++++----------- xen/arch/x86/cpu/microcode/core.c | 20 +++++++++++++++++++- 3 files changed, 28 insertions(+), 12 deletions(-)
Multiple downstream distros have tried passing discrete CPIO archives and
tripped over this not working. It turns out to be easy to support, so do so.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Teddy Astie <teddy.astie@vates.tech>
v2:
* Docs update too.
* Set opt_scan in early_microcode_load() so microcode_init_cache() operates
properly
---
CHANGELOG.md | 1 +
docs/misc/xen-command-line.pandoc | 19 ++++++++-----------
xen/arch/x86/cpu/microcode/core.c | 20 +++++++++++++++++++-
3 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 18f3d10f20d2..c191e504aba9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Support for Bus Lock Threshold on AMD Zen5 and later CPUs, used by Xen to
mitigate (by rate-limiting) the system wide impact of an HVM guest
misusing atomic instructions.
+ - Support for CPIO microcode in discrete multiboot modules.
### Removed
- On x86:
diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
index c1f2def9f99c..ebdca007d26b 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -2764,23 +2764,20 @@ Controls for CPU microcode loading, available when `CONFIG_MICROCODE_LOADING`
is enabled.
In order to load microcode at boot, Xen needs to find a suitable update
-amongst the modules provided by the bootloader. Two kinds of microcode update
-are supported:
+amongst the modules provided by the bootloader. Two formats are supported:
1. Raw microcode containers. The format of the container is CPU vendor
specific.
- 2. CPIO archive. This is Linux's preferred mechanism, and involves having
- the raw containers expressed as files
+ 2. CPIO archive, which involves having the raw containers expressed as files
(e.g. `kernel/x86/microcode/{GenuineIntel,AuthenticAMD}.bin`) in a CPIO
- archive, typically prepended to the initrd.
+ archive. Linux commonly prepends this to the initrd.
-The `<integer>` and `scan=<bool>` options are mutually exclusive and select
-between these two options. Further restrictions exist for booting xen.efi
-(see below).
+The `<integer>` and `scan=<bool>` options are mutually exclusive and work as
+follows. Further restrictions exist for booting xen.efi (see below).
- * The `<integer>` option nominates a specific multiboot module as a raw
- container (option 1 above). Valid options start from 1 (module 0 is
+ * The `<integer>` option nominates a specific multiboot module as containing
+ microcode in either format. Valid options start from 1 (module 0 is
always the dom0 kernel). A negative number may be used, and will
back-reference from the end of the module list. i.e. `ucode=-1` will
nominate the final multiboot module.
@@ -2794,7 +2791,7 @@ When booting xen.efi natively, the concept of multiboot modules doesn't exist.
Instead:
* In the [EFI configuration file](efi.html), `ucode=<filename>` can be used
- to identify a file as a raw container (option 1 above). Use of this
+ to identify a file as containing microcode in either format. Use of this
mechanism will disable both `<integer>` and `scan=`.
* If `ucode=<filename>` in the EFI configuration file is not used, it is
diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c
index ea0b35c4991d..9b8d1e09cb98 100644
--- a/xen/arch/x86/cpu/microcode/core.c
+++ b/xen/arch/x86/cpu/microcode/core.c
@@ -767,6 +767,7 @@ static int __init early_microcode_load(struct boot_info *bi)
void *data = NULL;
size_t size;
const struct microcode_patch *patch;
+ struct cpio_data cd;
int idx = opt_mod_idx;
int rc;
@@ -783,7 +784,6 @@ static int __init early_microcode_load(struct boot_info *bi)
for ( idx = 0; idx < bi->nr_modules; ++idx )
{
const struct boot_module *bm = &bi->mods[idx];
- struct cpio_data cd;
/* Search anything unclaimed or likely to be a CPIO archive. */
if ( bm->kind != BOOTMOD_UNKNOWN && bm->kind != BOOTMOD_RAMDISK )
@@ -851,6 +851,24 @@ static int __init early_microcode_load(struct boot_info *bi)
idx, size);
return -ENODEV;
}
+
+ /*
+ * If this blob appears to be a CPIO archive, try interpreting it as
+ * one. Otherwise treat it as a raw vendor blob.
+ */
+ cd = find_cpio_data(ucode_ops.cpio_path, data, size);
+ if ( cd.data )
+ {
+ data = cd.data;
+ size = cd.size;
+
+ /*
+ * (Ab)use opt_scan to inform microcode_init_cache() that
+ * early_mod_idx refers to a CPIO archive.
+ */
+ opt_scan = true;
+ }
+
goto found;
}
base-commit: 5eb84d6c992cf4e81936872c441b649057947442
--
2.39.5
Le 23/02/2026 à 19:52, Andrew Cooper a écrit :
> Multiple downstream distros have tried passing discrete CPIO archives and
> tripped over this not working. It turns out to be easy to support, so do so.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Tested-by: Teddy Astie <teddy.astie@vates.tech>
> ---
> CC: Jan Beulich <JBeulich@suse.com>
> CC: Roger Pau Monné <roger.pau@citrix.com>
> CC: Teddy Astie <teddy.astie@vates.tech>
>
> v2:
> * Docs update too.
> * Set opt_scan in early_microcode_load() so microcode_init_cache() operates
> properly
> ---
> CHANGELOG.md | 1 +
> docs/misc/xen-command-line.pandoc | 19 ++++++++-----------
> xen/arch/x86/cpu/microcode/core.c | 20 +++++++++++++++++++-
> 3 files changed, 28 insertions(+), 12 deletions(-)
>
> diff --git a/CHANGELOG.md b/CHANGELOG.md
> index 18f3d10f20d2..c191e504aba9 100644
> --- a/CHANGELOG.md
> +++ b/CHANGELOG.md
> @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
> - Support for Bus Lock Threshold on AMD Zen5 and later CPUs, used by Xen to
> mitigate (by rate-limiting) the system wide impact of an HVM guest
> misusing atomic instructions.
> + - Support for CPIO microcode in discrete multiboot modules.
>
> ### Removed
> - On x86:
> diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
> index c1f2def9f99c..ebdca007d26b 100644
> --- a/docs/misc/xen-command-line.pandoc
> +++ b/docs/misc/xen-command-line.pandoc
> @@ -2764,23 +2764,20 @@ Controls for CPU microcode loading, available when `CONFIG_MICROCODE_LOADING`
> is enabled.
>
> In order to load microcode at boot, Xen needs to find a suitable update
> -amongst the modules provided by the bootloader. Two kinds of microcode update
> -are supported:
> +amongst the modules provided by the bootloader. Two formats are supported:
>
> 1. Raw microcode containers. The format of the container is CPU vendor
> specific.
>
> - 2. CPIO archive. This is Linux's preferred mechanism, and involves having
> - the raw containers expressed as files
> + 2. CPIO archive, which involves having the raw containers expressed as files
> (e.g. `kernel/x86/microcode/{GenuineIntel,AuthenticAMD}.bin`) in a CPIO
> - archive, typically prepended to the initrd.
> + archive. Linux commonly prepends this to the initrd.
>
> -The `<integer>` and `scan=<bool>` options are mutually exclusive and select
> -between these two options. Further restrictions exist for booting xen.efi
> -(see below).
> +The `<integer>` and `scan=<bool>` options are mutually exclusive and work as
> +follows. Further restrictions exist for booting xen.efi (see below).
>
> - * The `<integer>` option nominates a specific multiboot module as a raw
> - container (option 1 above). Valid options start from 1 (module 0 is
> + * The `<integer>` option nominates a specific multiboot module as containing
> + microcode in either format. Valid options start from 1 (module 0 is
> always the dom0 kernel). A negative number may be used, and will
> back-reference from the end of the module list. i.e. `ucode=-1` will
> nominate the final multiboot module.
> @@ -2794,7 +2791,7 @@ When booting xen.efi natively, the concept of multiboot modules doesn't exist.
> Instead:
>
> * In the [EFI configuration file](efi.html), `ucode=<filename>` can be used
> - to identify a file as a raw container (option 1 above). Use of this
> + to identify a file as containing microcode in either format. Use of this
> mechanism will disable both `<integer>` and `scan=`.
>
> * If `ucode=<filename>` in the EFI configuration file is not used, it is
> diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c
> index ea0b35c4991d..9b8d1e09cb98 100644
> --- a/xen/arch/x86/cpu/microcode/core.c
> +++ b/xen/arch/x86/cpu/microcode/core.c
> @@ -767,6 +767,7 @@ static int __init early_microcode_load(struct boot_info *bi)
> void *data = NULL;
> size_t size;
> const struct microcode_patch *patch;
> + struct cpio_data cd;
> int idx = opt_mod_idx;
> int rc;
>
> @@ -783,7 +784,6 @@ static int __init early_microcode_load(struct boot_info *bi)
> for ( idx = 0; idx < bi->nr_modules; ++idx )
> {
> const struct boot_module *bm = &bi->mods[idx];
> - struct cpio_data cd;
>
> /* Search anything unclaimed or likely to be a CPIO archive. */
> if ( bm->kind != BOOTMOD_UNKNOWN && bm->kind != BOOTMOD_RAMDISK )
> @@ -851,6 +851,24 @@ static int __init early_microcode_load(struct boot_info *bi)
> idx, size);
> return -ENODEV;
> }
> +
> + /*
> + * If this blob appears to be a CPIO archive, try interpreting it as
> + * one. Otherwise treat it as a raw vendor blob.
> + */
> + cd = find_cpio_data(ucode_ops.cpio_path, data, size);
> + if ( cd.data )
> + {
> + data = cd.data;
> + size = cd.size;
> +
> + /*
> + * (Ab)use opt_scan to inform microcode_init_cache() that
> + * early_mod_idx refers to a CPIO archive.
> + */
> + opt_scan = true;
> + }
> +
> goto found;
> }
>
>
> base-commit: 5eb84d6c992cf4e81936872c441b649057947442
--
Teddy Astie | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
On 23.02.2026 19:50, Andrew Cooper wrote: > Multiple downstream distros have tried passing discrete CPIO archives and > tripped over this not working. It turns out to be easy to support, so do so. > > Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
© 2016 - 2026 Red Hat, Inc.