From mboxrd@z Thu Jan 1 00:00:00 1970 From: Konrad Rzeszutek Wilk Subject: [PATCH] microcode: Check whether the microcode is correct. Date: Thu, 18 Jul 2013 23:59:23 -0400 Message-ID: <1374206363-19001-2-git-send-email-konrad.wilk@oracle.com> References: <1374165371-24716-1-git-send-email-konrad.wilk@oracle.com> <1374206363-19001-1-git-send-email-konrad.wilk@oracle.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1374206363-19001-1-git-send-email-konrad.wilk@oracle.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: JBeulich@suse.com, xen-devel@lists.xensource.com, david.vrabel@citrix.com List-Id: xen-devel@lists.xenproject.org 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 --- 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(µcode_percpu_nfb); -- 1.7.7.6