[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] x86/ucode: Support discrete modules being CPIO archives



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@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
CC: Teddy Astie <teddy.astie@xxxxxxxxxx>

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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.