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

[Xen-devel] [PATCH] microcode: Check whether the microcode is correct.



We do the microcode code update in two steps - the presmp:
 'microcode_presmp_init' and when CPUs are brought up:
'microcode_init'. The earlier performs the microcode update
on the BSP - but unfortunately it does not check whether the
update failed. Which means that we might try later to update
a incorrect payload on the rest of CPUs.

Furthermore now that the ucode= parameter can specify two
sources of microcode blob we have to be cognizant whether
both (or either) of the payloads are correct.

For example, the user could have constructed the cpio archive
with a empty GenuineIntel.bin file and provided the correct
GenuineIntel.bin as a seperate payload:

xen.gz ucode=2,initrd --- vmlinuz --- initramfs.cpio.gz --- GenuineIntel.bin

[the initramfs.cpio.gz has the cpio archive of the empty file
kernel/x86/microcode/GenuineIntel.bin pre-pended]

in which case we need to skip the microcode payload from the
initramfs.cpio.gz and use the GenuineIntel.bin payload.

Or if the user mishandled the GenuineIntel.bin seperate payload and
had the initramfs.cpio.gz correct. Or if both payloads had
bogus data.

This patch handles these odd situations.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
---
 xen/arch/x86/microcode.c |   52 ++++++++++++++++++++++++++++++----------------
 1 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c
index b191e9f..2ab2b46 100644
--- a/xen/arch/x86/microcode.c
+++ b/xen/arch/x86/microcode.c
@@ -433,24 +433,40 @@ static int __init microcode_presmp_init(void)
     {
         if ( ucode_mod.mod_end || ucode_blob.size )
         {
-            void *data;
-            size_t len;
-
-            if ( ucode_blob.size )
-            {
-                len = ucode_blob.size;
-                data = ucode_blob.data;
-            }
-            else
-            {
-                len = ucode_mod.mod_end;
-                data = ucode_mod_map(&ucode_mod);
-            }
-            if ( data )
-                microcode_update_cpu(data, len);
-
-            if ( !ucode_blob.size )
-                ucode_mod_map(NULL);
+            int rc;
+            do {
+                void *data = NULL;
+                size_t len;
+
+                rc = 0;
+                if ( ucode_blob.size )
+                {
+                    len = ucode_blob.size;
+                    data = ucode_blob.data;
+                }
+                else if ( ucode_mod.mod_end )
+                {
+                    len = ucode_mod.mod_end;
+                    data = ucode_mod_map(&ucode_mod);
+                }
+                if ( data )
+                    rc = microcode_update_cpu(data, len);
+
+                if ( !ucode_blob.size && ucode_mod.mod_end )
+                    ucode_mod_map(NULL);
+
+                if ( rc == -EINVAL )
+                {
+                    if ( ucode_blob.size ) /* That was tried first */
+                    {
+                        ucode_blob.size = 0;
+                        xfree(ucode_blob.data);
+                        continue;
+                    }
+                    if ( ucode_mod.mod_end )
+                        ucode_mod.mod_end = 0;
+                }
+            } while ( rc );
         }
 
         register_cpu_notifier(&microcode_percpu_nfb);
-- 
1.7.7.6


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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