[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(µcode_percpu_nfb); -- 1.7.7.6 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |