[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 4/5] x86/ucode: Cache results in microcode_scan_module()
When microcode_scan_module() is used, it's used twice. The caching of the bootstrap_map() pointer in ucode_blob.data is buggy for multiple reasons and is going to be removed. Right now, the boot flow depends on the second pass over bootstrap_map()/find_cpio_data() altering ucode_blob.data to use the directmap alias of the CPIO module, where previously it caches the early boostrap mapping. If the scan is successful, it will be successful the second time too, but there's no point repeating the work. Cache the module index, offset and size to short circuit things the second time around. While rearranging this, reduce the scope of the internals of the loop, changing the type of _blob_start to void and droping the dead stores into cd. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Roger Pau Monné <roger.pau@xxxxxxxxxx> CC: Wei Liu <wl@xxxxxxx> CC: Sergey Dyasli <sergey.dyasli@xxxxxxxxxx> --- xen/arch/x86/cpu/microcode/core.c | 34 ++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c index 4d2a896fe78d..7d32bc13db6f 100644 --- a/xen/arch/x86/cpu/microcode/core.c +++ b/xen/arch/x86/cpu/microcode/core.c @@ -152,14 +152,30 @@ void __init microcode_scan_module( unsigned long *module_map, const multiboot_info_t *mbi) { + static __initdata struct { /* Cached details of a previous successful scan. */ + unsigned long offset; /* Offset from the start of the CPIO archive. */ + unsigned long size; /* Size of the CPIO file. */ + unsigned int mod_idx; /* Which multiboot module the CPIO archive is. */ + } scan; + module_t *mod = (module_t *)__va(mbi->mods_addr); - uint64_t *_blob_start; - unsigned long _blob_size; - struct cpio_data cd; const char *p = NULL; int i; ucode_blob.size = 0; + + if ( scan.mod_idx ) /* Previous scan was successful. */ + { + void *map = bootstrap_map(&mod[scan.mod_idx]); + + if ( !map ) + return; + + ucode_blob.size = scan.size; + ucode_blob.data = map + scan.offset; + return; + } + if ( !ucode_scan ) return; @@ -175,6 +191,10 @@ void __init microcode_scan_module( */ for ( i = 1 /* Ignore dom0 kernel */; i < mbi->mods_count; i++ ) { + void *_blob_start; + unsigned long _blob_size; + struct cpio_data cd; + if ( !test_bit(i, module_map) ) continue; @@ -186,15 +206,19 @@ void __init microcode_scan_module( i, _blob_size); continue; } - cd.data = NULL; - cd.size = 0; + cd = find_cpio_data(p, _blob_start, _blob_size); if ( cd.data ) { + scan.mod_idx = i; + scan.offset = cd.data - _blob_start; + scan.size = cd.size; + ucode_blob.size = cd.size; ucode_blob.data = cd.data; break; } + bootstrap_map(NULL); } } -- 2.30.2
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |