diff options
Diffstat (limited to 'arch/x86/kernel/cpu/microcode/intel.c')
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/intel.c | 24 | 
1 files changed, 22 insertions, 2 deletions
| diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index afdfd237b59f..59edbe9d4ccb 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -42,7 +42,7 @@  static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin";  /* Current microcode patch used in early patching on the APs. */ -struct microcode_intel *intel_ucode_patch; +static struct microcode_intel *intel_ucode_patch;  static inline bool cpu_signatures_match(unsigned int s1, unsigned int p1,  					unsigned int s2, unsigned int p2) @@ -166,7 +166,7 @@ static struct ucode_patch *__alloc_microcode_buf(void *data, unsigned int size)  static void save_microcode_patch(void *data, unsigned int size)  {  	struct microcode_header_intel *mc_hdr, *mc_saved_hdr; -	struct ucode_patch *iter, *tmp, *p; +	struct ucode_patch *iter, *tmp, *p = NULL;  	bool prev_found = false;  	unsigned int sig, pf; @@ -202,6 +202,18 @@ static void save_microcode_patch(void *data, unsigned int size)  		else  			list_add_tail(&p->plist, µcode_cache);  	} + +	/* +	 * Save for early loading. On 32-bit, that needs to be a physical +	 * address as the APs are running from physical addresses, before +	 * paging has been enabled. +	 */ +	if (p) { +		if (IS_ENABLED(CONFIG_X86_32)) +			intel_ucode_patch = (struct microcode_intel *)__pa_nodebug(p->data); +		else +			intel_ucode_patch = p->data; +	}  }  static int microcode_sanity_check(void *mc, int print_err) @@ -607,6 +619,14 @@ int __init save_microcode_in_initrd_intel(void)  	struct ucode_cpu_info uci;  	struct cpio_data cp; +	/* +	 * initrd is going away, clear patch ptr. We will scan the microcode one +	 * last time before jettisoning and save a patch, if found. Then we will +	 * update that pointer too, with a stable patch address to use when +	 * resuming the cores. +	 */ +	intel_ucode_patch = NULL; +  	if (!load_builtin_intel_microcode(&cp))  		cp = find_microcode_in_initrd(ucode_path, false); |