3333static const char ucode_path [] = "kernel/x86/microcode/GenuineIntel.bin" ;
3434
3535/* Current microcode patch used in early patching on the APs. */
36- static struct microcode_intel * intel_ucode_patch ;
36+ static struct microcode_intel * intel_ucode_patch __read_mostly ;
3737
3838/* last level cache size per core */
39- static int llc_size_per_core ;
39+ static int llc_size_per_core __ro_after_init ;
4040
4141/* microcode format is extended from prescott processors */
4242struct extended_signature {
@@ -253,74 +253,17 @@ static int has_newer_microcode(void *mc, unsigned int csig, int cpf, int new_rev
253253 return intel_find_matching_signature (mc , csig , cpf );
254254}
255255
256- static struct ucode_patch * memdup_patch (void * data , unsigned int size )
256+ static void save_microcode_patch (void * data , unsigned int size )
257257{
258- struct ucode_patch * p ;
259-
260- p = kzalloc (sizeof (struct ucode_patch ), GFP_KERNEL );
261- if (!p )
262- return NULL ;
263-
264- p -> data = kmemdup (data , size , GFP_KERNEL );
265- if (!p -> data ) {
266- kfree (p );
267- return NULL ;
268- }
269-
270- return p ;
271- }
272-
273- static void save_microcode_patch (struct ucode_cpu_info * uci , void * data , unsigned int size )
274- {
275- struct microcode_header_intel * mc_hdr , * mc_saved_hdr ;
276- struct ucode_patch * iter , * tmp , * p = NULL ;
277- bool prev_found = false;
278- unsigned int sig , pf ;
279-
280- mc_hdr = (struct microcode_header_intel * )data ;
281-
282- list_for_each_entry_safe (iter , tmp , & microcode_cache , plist ) {
283- mc_saved_hdr = (struct microcode_header_intel * )iter -> data ;
284- sig = mc_saved_hdr -> sig ;
285- pf = mc_saved_hdr -> pf ;
286-
287- if (intel_find_matching_signature (data , sig , pf )) {
288- prev_found = true;
289-
290- if (mc_hdr -> rev <= mc_saved_hdr -> rev )
291- continue ;
292-
293- p = memdup_patch (data , size );
294- if (!p )
295- pr_err ("Error allocating buffer %p\n" , data );
296- else {
297- list_replace (& iter -> plist , & p -> plist );
298- kfree (iter -> data );
299- kfree (iter );
300- }
301- }
302- }
303-
304- /*
305- * There weren't any previous patches found in the list cache; save the
306- * newly found.
307- */
308- if (!prev_found ) {
309- p = memdup_patch (data , size );
310- if (!p )
311- pr_err ("Error allocating buffer for %p\n" , data );
312- else
313- list_add_tail (& p -> plist , & microcode_cache );
314- }
258+ struct microcode_header_intel * p ;
315259
260+ p = kmemdup (data , size , GFP_KERNEL );
316261 if (!p )
317262 return ;
318263
319- if (!intel_find_matching_signature (p -> data , uci -> cpu_sig .sig , uci -> cpu_sig .pf ))
320- return ;
321-
264+ kfree (intel_ucode_patch );
322265 /* Save for early loading */
323- intel_ucode_patch = p -> data ;
266+ intel_ucode_patch = ( struct microcode_intel * ) p ;
324267}
325268
326269/*
@@ -332,6 +275,7 @@ scan_microcode(void *data, size_t size, struct ucode_cpu_info *uci, bool save)
332275{
333276 struct microcode_header_intel * mc_header ;
334277 struct microcode_intel * patch = NULL ;
278+ u32 cur_rev = uci -> cpu_sig .rev ;
335279 unsigned int mc_size ;
336280
337281 while (size ) {
@@ -341,8 +285,7 @@ scan_microcode(void *data, size_t size, struct ucode_cpu_info *uci, bool save)
341285 mc_header = (struct microcode_header_intel * )data ;
342286
343287 mc_size = get_totalsize (mc_header );
344- if (!mc_size ||
345- mc_size > size ||
288+ if (!mc_size || mc_size > size ||
346289 intel_microcode_sanity_check (data , false, MC_HEADER_TYPE_MICROCODE ) < 0 )
347290 break ;
348291
@@ -354,31 +297,16 @@ scan_microcode(void *data, size_t size, struct ucode_cpu_info *uci, bool save)
354297 continue ;
355298 }
356299
357- if ( save ) {
358- save_microcode_patch ( uci , data , mc_size );
300+ /* BSP scan: Check whether there is newer microcode */
301+ if (! save && cur_rev >= mc_header -> rev )
359302 goto next ;
360- }
361-
362-
363- if (!patch ) {
364- if (!has_newer_microcode (data ,
365- uci -> cpu_sig .sig ,
366- uci -> cpu_sig .pf ,
367- uci -> cpu_sig .rev ))
368- goto next ;
369303
370- } else {
371- struct microcode_header_intel * phdr = & patch -> hdr ;
372-
373- if (!has_newer_microcode (data ,
374- phdr -> sig ,
375- phdr -> pf ,
376- phdr -> rev ))
377- goto next ;
378- }
304+ /* Save scan: Check whether there is newer or matching microcode */
305+ if (save && cur_rev != mc_header -> rev )
306+ goto next ;
379307
380- /* We have a newer patch, save it. */
381308 patch = data ;
309+ cur_rev = mc_header -> rev ;
382310
383311next :
384312 data += mc_size ;
@@ -387,6 +315,9 @@ scan_microcode(void *data, size_t size, struct ucode_cpu_info *uci, bool save)
387315 if (size )
388316 return NULL ;
389317
318+ if (save && patch )
319+ save_microcode_patch (patch , mc_size );
320+
390321 return patch ;
391322}
392323
@@ -528,26 +459,10 @@ void load_ucode_intel_ap(void)
528459 apply_microcode_early (& uci );
529460}
530461
531- static struct microcode_intel * find_patch (struct ucode_cpu_info * uci )
462+ /* Accessor for microcode pointer */
463+ static struct microcode_intel * ucode_get_patch (void )
532464{
533- struct microcode_header_intel * phdr ;
534- struct ucode_patch * iter , * tmp ;
535-
536- list_for_each_entry_safe (iter , tmp , & microcode_cache , plist ) {
537-
538- phdr = (struct microcode_header_intel * )iter -> data ;
539-
540- if (phdr -> rev <= uci -> cpu_sig .rev )
541- continue ;
542-
543- if (!intel_find_matching_signature (phdr ,
544- uci -> cpu_sig .sig ,
545- uci -> cpu_sig .pf ))
546- continue ;
547-
548- return iter -> data ;
549- }
550- return NULL ;
465+ return intel_ucode_patch ;
551466}
552467
553468void reload_ucode_intel (void )
@@ -557,7 +472,7 @@ void reload_ucode_intel(void)
557472
558473 intel_cpu_collect_info (& uci );
559474
560- p = find_patch ( & uci );
475+ p = ucode_get_patch ( );
561476 if (!p )
562477 return ;
563478
@@ -601,7 +516,7 @@ static enum ucode_state apply_microcode_intel(int cpu)
601516 return UCODE_ERROR ;
602517
603518 /* Look for a newer patch in our cache: */
604- mc = find_patch ( uci );
519+ mc = ucode_get_patch ( );
605520 if (!mc ) {
606521 mc = uci -> mc ;
607522 if (!mc )
@@ -730,7 +645,7 @@ static enum ucode_state generic_load_microcode(int cpu, struct iov_iter *iter)
730645 uci -> mc = (struct microcode_intel * )new_mc ;
731646
732647 /* Save for CPU hotplug */
733- save_microcode_patch (uci , new_mc , new_mc_size );
648+ save_microcode_patch (new_mc , new_mc_size );
734649
735650 pr_debug ("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n" ,
736651 cpu , new_rev , uci -> cpu_sig .rev );
0 commit comments