x86/AMD-ucode: correct multiple container handling
authorJan Beulich <JBeulich@suse.com>
Mon, 15 Dec 2014 09:16:09 +0000 (09:16 +0000)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Mon, 5 Jan 2015 15:20:31 +0000 (10:20 -0500)
Avoid emitting an error message referring to an incorrect or corrupt
container file just because no entry was found for the running CPU.

Additionally switch the order of data validation and consumption in
cpu_request_microcode()'s first loop, and also check the types of
skipped blocks in container_fast_forward().

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
Release-Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
xen/arch/x86/microcode_amd.c

index b68cf937317fdb4fbe1dfbdaf15ed5708532cbf2..f79b397e348b32bca09e49e49df15bea48e4aba0 100644 (file)
@@ -331,12 +331,17 @@ static int container_fast_forward(const void *data, size_t size_left, size_t *of
              header[1] == UCODE_EQUIV_CPU_TABLE_TYPE )
             break;
 
+        if ( header[0] != UCODE_UCODE_TYPE )
+            return -EINVAL;
         size = header[1] + SECTION_HDR_SIZE;
         if ( size < PATCH_HDR_SIZE || size_left < size )
             return -EINVAL;
 
         size_left -= size;
         *offset += size;
+
+        if ( !size_left )
+            return -ENODATA;
     }
 
     return 0;
@@ -386,10 +391,6 @@ static int cpu_request_microcode(int cpu, const void *buf, size_t bufsize)
             break;
         }
 
-        if ( find_equiv_cpu_id(mc_amd->equiv_cpu_table, current_cpu_id,
-                               &equiv_cpu_id) )
-                break;
-
         /*
          * Could happen as we advance 'offset' early
          * in install_equiv_cpu_table
@@ -401,7 +402,16 @@ static int cpu_request_microcode(int cpu, const void *buf, size_t bufsize)
             break;
         }
 
+        if ( find_equiv_cpu_id(mc_amd->equiv_cpu_table, current_cpu_id,
+                               &equiv_cpu_id) )
+            break;
+
         error = container_fast_forward(buf, bufsize - offset, &offset);
+        if ( error == -ENODATA )
+        {
+            ASSERT(offset == bufsize);
+            break;
+        }
         if ( error )
         {
             printk(KERN_ERR "microcode: CPU%d incorrect or corrupt container file\n"