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); | 	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 | #else | ||||||
| void load_ucode_amd_ap(void) | void load_ucode_amd_ap(void) | ||||||
| { | { | ||||||
|  | @ -337,31 +346,37 @@ void load_ucode_amd_ap(void) | ||||||
| 
 | 
 | ||||||
| int __init save_microcode_in_initrd_amd(void) | int __init save_microcode_in_initrd_amd(void) | ||||||
| { | { | ||||||
|  | 	unsigned long cont; | ||||||
| 	enum ucode_state ret; | 	enum ucode_state ret; | ||||||
| 	u32 eax; | 	u32 eax; | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_X86_32 | 	if (!container) | ||||||
| 	unsigned int bsp = boot_cpu_data.cpu_index; | 		return -EINVAL; | ||||||
| 	struct ucode_cpu_info *uci = ucode_cpu_info + bsp; |  | ||||||
| 
 | 
 | ||||||
| 	if (!uci->cpu_sig.sig) | #ifdef CONFIG_X86_32 | ||||||
| 		smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1); | 	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 | 	 * Take into account the fact that the ramdisk might get relocated and | ||||||
| 	 * and therefore we need to recompute the container's position in | 	 * therefore we need to recompute the container's position in virtual | ||||||
| 	 * virtual memory space. | 	 * memory space. | ||||||
| 	 */ | 	 */ | ||||||
| 	container = (u8 *)(__va((u32)relocated_ramdisk) + | 	if (relocated_ramdisk) | ||||||
| 			   ((u32)container - boot_params.hdr.ramdisk_image)); | 		container = (u8 *)(__va(relocated_ramdisk) + | ||||||
| #endif | 			     (cont - boot_params.hdr.ramdisk_image)); | ||||||
|  | 
 | ||||||
| 	if (ucode_new_rev) | 	if (ucode_new_rev) | ||||||
| 		pr_info("microcode: updated early to new patch_level=0x%08x\n", | 		pr_info("microcode: updated early to new patch_level=0x%08x\n", | ||||||
| 			ucode_new_rev); | 			ucode_new_rev); | ||||||
| 
 | 
 | ||||||
| 	if (!container) |  | ||||||
| 		return -EINVAL; |  | ||||||
| 
 |  | ||||||
| 	eax   = cpuid_eax(0x00000001); | 	eax   = cpuid_eax(0x00000001); | ||||||
| 	eax   = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); | 	eax   = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Borislav Petkov
				Borislav Petkov