diff options
Diffstat (limited to 'arch/x86/kernel/cpu/microcode/intel.c')
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/intel.c | 63 | 
1 files changed, 10 insertions, 53 deletions
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 6a99535d7f37..7e8e07bddd5f 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -100,53 +100,6 @@ static int has_newer_microcode(void *mc, unsigned int csig, int cpf, int new_rev  	return find_matching_signature(mc, csig, cpf);  } -/* - * Given CPU signature and a microcode patch, this function finds if the - * microcode patch has matching family and model with the CPU. - * - * %true - if there's a match - * %false - otherwise - */ -static bool microcode_matches(struct microcode_header_intel *mc_header, -			      unsigned long sig) -{ -	unsigned long total_size = get_totalsize(mc_header); -	unsigned long data_size = get_datasize(mc_header); -	struct extended_sigtable *ext_header; -	unsigned int fam_ucode, model_ucode; -	struct extended_signature *ext_sig; -	unsigned int fam, model; -	int ext_sigcount, i; - -	fam   = x86_family(sig); -	model = x86_model(sig); - -	fam_ucode   = x86_family(mc_header->sig); -	model_ucode = x86_model(mc_header->sig); - -	if (fam == fam_ucode && model == model_ucode) -		return true; - -	/* Look for ext. headers: */ -	if (total_size <= data_size + MC_HEADER_SIZE) -		return false; - -	ext_header   = (void *) mc_header + data_size + MC_HEADER_SIZE; -	ext_sig      = (void *)ext_header + EXT_HEADER_SIZE; -	ext_sigcount = ext_header->count; - -	for (i = 0; i < ext_sigcount; i++) { -		fam_ucode   = x86_family(ext_sig->sig); -		model_ucode = x86_model(ext_sig->sig); - -		if (fam == fam_ucode && model == model_ucode) -			return true; - -		ext_sig++; -	} -	return false; -} -  static struct ucode_patch *memdup_patch(void *data, unsigned int size)  {  	struct ucode_patch *p; @@ -164,7 +117,7 @@ static struct ucode_patch *memdup_patch(void *data, unsigned int size)  	return p;  } -static void save_microcode_patch(void *data, unsigned int size) +static void save_microcode_patch(struct ucode_cpu_info *uci, void *data, unsigned int size)  {  	struct microcode_header_intel *mc_hdr, *mc_saved_hdr;  	struct ucode_patch *iter, *tmp, *p = NULL; @@ -210,6 +163,9 @@ static void save_microcode_patch(void *data, unsigned int size)  	if (!p)  		return; +	if (!find_matching_signature(p->data, uci->cpu_sig.sig, uci->cpu_sig.pf)) +		return; +  	/*  	 * Save for early loading. On 32-bit, that needs to be a physical  	 * address as the APs are running from physical addresses, before @@ -344,13 +300,14 @@ scan_microcode(void *data, size_t size, struct ucode_cpu_info *uci, bool save)  		size -= mc_size; -		if (!microcode_matches(mc_header, uci->cpu_sig.sig)) { +		if (!find_matching_signature(data, uci->cpu_sig.sig, +					     uci->cpu_sig.pf)) {  			data += mc_size;  			continue;  		}  		if (save) { -			save_microcode_patch(data, mc_size); +			save_microcode_patch(uci, data, mc_size);  			goto next;  		} @@ -483,14 +440,14 @@ static void show_saved_mc(void)   * Save this microcode patch. It will be loaded early when a CPU is   * hot-added or resumes.   */ -static void save_mc_for_early(u8 *mc, unsigned int size) +static void save_mc_for_early(struct ucode_cpu_info *uci, u8 *mc, unsigned int size)  {  	/* Synchronization during CPU hotplug. */  	static DEFINE_MUTEX(x86_cpu_microcode_mutex);  	mutex_lock(&x86_cpu_microcode_mutex); -	save_microcode_patch(mc, size); +	save_microcode_patch(uci, mc, size);  	show_saved_mc();  	mutex_unlock(&x86_cpu_microcode_mutex); @@ -935,7 +892,7 @@ static enum ucode_state generic_load_microcode(int cpu, struct iov_iter *iter)  	 * permanent memory. So it will be loaded early when a CPU is hot added  	 * or resumes.  	 */ -	save_mc_for_early(new_mc, new_mc_size); +	save_mc_for_early(uci, new_mc, new_mc_size);  	pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",  		 cpu, new_rev, uci->cpu_sig.rev);  | 
