x86, microcode, AMD: Unify valid container checks
For additional coverage, BorisO and friends unknowlingly did swap AMD microcode with Intel microcode blobs in order to see what happens. What did happen on 32-bit was [ 5.722656] BUG: unable to handle kernel paging request at be3a6008 [ 5.722693] IP: [<c106d6b4>] load_microcode_amd+0x24/0x3f0 [ 5.722716] *pdpt = 0000000000000000 *pde = 0000000000000000 because there was a valid initrd there but without valid microcode in it and the container check happened *after* the relocated ramdisk handling on 32-bit, which was clearly wrong. While at it, take care of the ramdisk relocation on both 32- and 64-bit as it is done on both. Also, comment what we're doing because this code is a bit tricky. Reported-and-tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Signed-off-by: Borislav Petkov <bp@suse.de> Link: http://lkml.kernel.org/r/1391460104-7261-1-git-send-email-bp@alien8.de Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
		
					parent
					
						
							
								6583327c4d
							
						
					
				
			
			
				commit
				
					
						75a1ba5b2c
					
				
			
		
					 1 changed files with 29 additions and 14 deletions
				
			
		|  | @ -285,6 +285,15 @@ static void __init collect_cpu_sig_on_bsp(void *arg) | |||
| 
 | ||||
| 	uci->cpu_sig.sig = cpuid_eax(0x00000001); | ||||
| } | ||||
| 
 | ||||
| static void __init get_bsp_sig(void) | ||||
| { | ||||
| 	unsigned int bsp = boot_cpu_data.cpu_index; | ||||
| 	struct ucode_cpu_info *uci = ucode_cpu_info + bsp; | ||||
| 
 | ||||
| 	if (!uci->cpu_sig.sig) | ||||
| 		smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1); | ||||
| } | ||||
| #else | ||||
| void load_ucode_amd_ap(void) | ||||
| { | ||||
|  | @ -337,31 +346,37 @@ void load_ucode_amd_ap(void) | |||
| 
 | ||||
| int __init save_microcode_in_initrd_amd(void) | ||||
| { | ||||
| 	unsigned long cont; | ||||
| 	enum ucode_state ret; | ||||
| 	u32 eax; | ||||
| 
 | ||||
| #ifdef CONFIG_X86_32 | ||||
| 	unsigned int bsp = boot_cpu_data.cpu_index; | ||||
| 	struct ucode_cpu_info *uci = ucode_cpu_info + bsp; | ||||
| 	if (!container) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	if (!uci->cpu_sig.sig) | ||||
| 		smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1); | ||||
| #ifdef CONFIG_X86_32 | ||||
| 	get_bsp_sig(); | ||||
| 	cont = (unsigned long)container; | ||||
| #else | ||||
| 	/*
 | ||||
| 	 * We need the physical address of the container for both bitness since | ||||
| 	 * boot_params.hdr.ramdisk_image is a physical address. | ||||
| 	 */ | ||||
| 	cont = __pa(container); | ||||
| #endif | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Take into account the fact that the ramdisk might get relocated | ||||
| 	 * and therefore we need to recompute the container's position in | ||||
| 	 * virtual memory space. | ||||
| 	 * Take into account the fact that the ramdisk might get relocated and | ||||
| 	 * therefore we need to recompute the container's position in virtual | ||||
| 	 * memory space. | ||||
| 	 */ | ||||
| 	container = (u8 *)(__va((u32)relocated_ramdisk) + | ||||
| 			   ((u32)container - boot_params.hdr.ramdisk_image)); | ||||
| #endif | ||||
| 	if (relocated_ramdisk) | ||||
| 		container = (u8 *)(__va(relocated_ramdisk) + | ||||
| 			     (cont - boot_params.hdr.ramdisk_image)); | ||||
| 
 | ||||
| 	if (ucode_new_rev) | ||||
| 		pr_info("microcode: updated early to new patch_level=0x%08x\n", | ||||
| 			ucode_new_rev); | ||||
| 
 | ||||
| 	if (!container) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	eax   = cpuid_eax(0x00000001); | ||||
| 	eax   = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Borislav Petkov
				Borislav Petkov