--- arch/x86/kernel/microcode_intel_early.c | 101 ++++++++++++++++---------------- arch/x86/kernel/setup.c | 11 +++ 2 files changed, 64 insertions(+), 48 deletions(-) Index: linux-2.6/arch/x86/kernel/microcode_intel_early.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/microcode_intel_early.c +++ linux-2.6/arch/x86/kernel/microcode_intel_early.c @@ -20,9 +20,11 @@ #include #include #include + #include #include #include +#include struct microcode_intel __initdata *mc_saved_in_initrd[MAX_UCODE_COUNT]; struct mc_saved_data mc_saved_data; @@ -290,12 +292,44 @@ static int __cpuinit collect_cpu_info_ea return 0; } +#ifdef CONFIG_X86_64 +void __init update_mc_saved_data(unsigned long pa_offset) +{ + int i; + unsigned long addr; + + if (!pa_offset || !mc_saved_data.mc_saved) + return; + + for (i = 0; i< mc_saved_data.mc_saved_count; i++) + mc_saved_data.mc_saved[i] += pa_offset; +} +#else +void __init update_mc_saved_data(unsigned long pa_offset) +{ + int i; + + if (mc_saved_data.mc_saved) { + mc_saved_data.mc_saved = __va(mc_saved_data.mc_saved); + for (i = 0; i < mc_saved_data.mc_saved_count; i++) + mc_saved_data.mc_saved[i] = + __va(mc_saved_data.mc_saved[i] + pa_offset); + + } + + mc_saved_data.ucode_cpu_info = __va(mc_saved_data.ucode_cpu_info); + if (mc_saved_data.ucode_cpu_info->mc) + mc_saved_data.ucode_cpu_info->mc = + __va(mc_saved_data.ucode_cpu_info->mc); +} + +#endif + static __init enum ucode_state -scan_microcode(unsigned long start, unsigned long end, +scan_microcode(unsigned long start, unsigned long size, struct mc_saved_data *mc_saved_data, struct microcode_intel **mc_saved_in_initrd) { - unsigned int size = end - start + 1; struct cpio_data cd = { 0, 0 }; char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin"; long offset = 0; @@ -308,7 +342,7 @@ scan_microcode(unsigned long start, unsi mc_saved_in_initrd, SYSTEM_BOOTING); } -static int __init +static int __cpuinit apply_microcode_early(struct mc_saved_data *mc_saved_data, int cpu) { struct ucode_cpu_info *uci = mc_saved_data->ucode_cpu_info + cpu; @@ -339,32 +373,6 @@ apply_microcode_early(struct mc_saved_da return 0; } -#ifdef CONFIG_X86_32 -static void __init map_mc_saved(struct mc_saved_data *mc_saved_data, - struct microcode_intel **mc_saved_in_initrd) -{ - int i; - - if (mc_saved_data->mc_saved) { - for (i = 0; i < mc_saved_data->mc_saved_count; i++) - mc_saved_data->mc_saved[i] = - __va(mc_saved_data->mc_saved[i]); - - mc_saved_data->mc_saved = __va(mc_saved_data->mc_saved); - } - - if (mc_saved_data->ucode_cpu_info->mc) - mc_saved_data->ucode_cpu_info->mc = - __va(mc_saved_data->ucode_cpu_info->mc); - mc_saved_data->ucode_cpu_info = __va(mc_saved_data->ucode_cpu_info); -} -#else -static inline void __init map_mc_saved(struct mc_saved_data *mc_saved_data, - struct microcode_intel **mc_saved_in_initrd) -{ -} -#endif - void __init save_microcode_in_initrd(struct mc_saved_data *mc_saved_data, struct microcode_intel **mc_saved_in_initrd) { @@ -376,7 +384,7 @@ void __init save_microcode_in_initrd(str static void __init _load_ucode_intel_bsp(struct mc_saved_data *mc_saved_data, struct microcode_intel **mc_saved_in_initrd, - unsigned long initrd_start, unsigned long initrd_end) + unsigned long initrd_start, unsigned long initrd_size) { int cpu = 0; @@ -387,37 +395,34 @@ _load_ucode_intel_bsp(struct mc_saved_da (struct ucode_cpu_info *)__pa(ucode_cpu_info_early); #endif collect_cpu_info_early(mc_saved_data->ucode_cpu_info + cpu); - scan_microcode(initrd_start, initrd_end, mc_saved_data, + scan_microcode(initrd_start, initrd_size, mc_saved_data, mc_saved_in_initrd); load_microcode(mc_saved_data, cpu); apply_microcode_early(mc_saved_data, cpu); - map_mc_saved(mc_saved_data, mc_saved_in_initrd); } void __init load_ucode_intel_bsp(char *real_mode_data) { - u64 ramdisk_image, ramdisk_size, ramdisk_end; - unsigned long initrd_start, initrd_end; - struct boot_params *boot_params; - - boot_params = (struct boot_params *)real_mode_data; - ramdisk_image = boot_params->hdr.ramdisk_image; - ramdisk_size = boot_params->hdr.ramdisk_size; + u64 ramdisk_image, ramdisk_size; #ifdef CONFIG_X86_64 - ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); - initrd_start = ramdisk_image + PAGE_OFFSET; - initrd_end = initrd_start + ramdisk_size; + ramdisk_image = boot_params.hdr.ramdisk_image; + ramdisk_size = boot_params.hdr.ramdisk_size; + if (!ramdisk_image || !ramdisk_size) + return; _load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd, - initrd_start, initrd_end); + ramdisk_image, ramdisk_size); #else - ramdisk_end = ramdisk_image + ramdisk_size; - initrd_start = ramdisk_image; - initrd_end = initrd_start + ramdisk_size; + struct boot_params *boot_params = (struct boot_params *)real_mode_data; + + ramdisk_image = boot_params->hdr.ramdisk_image; + ramdisk_size = boot_params->hdr.ramdisk_size; + if (!ramdisk_image || !ramdisk_size) + return; _load_ucode_intel_bsp((struct mc_saved_data *)__pa(&mc_saved_data), - (struct microcode_intel **)__pa(mc_saved_in_initrd), - initrd_start, initrd_end); + (struct microcode_intel **)__pa(mc_saved_in_initrd), + ramdisk_image, ramdisk_size); #endif } Index: linux-2.6/arch/x86/kernel/setup.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup.c +++ linux-2.6/arch/x86/kernel/setup.c @@ -309,6 +309,14 @@ static u64 __init get_mem_size(unsigned #ifdef CONFIG_BLK_DEV_INITRD +#ifdef CONFIG_MICROCODE_INTEL_EARLY +void update_mc_saved_data(unsigned long pa_offset); +#else +static inline void update_mc_saved_data(unsigned long pa_offset) +{ +} +#endif + static u64 __init get_ramdisk_image(void) { u64 ramdisk_image = boot_params.hdr.ramdisk_image; @@ -376,6 +384,8 @@ static void __init relocate_initrd(void) " [mem %#010llx-%#010llx]\n", ramdisk_image, ramdisk_image + ramdisk_size - 1, ramdisk_here, ramdisk_here + ramdisk_size - 1); + + update_mc_saved_data(ramdisk_here - ramdisk_image); } static void __init early_reserve_initrd(void) @@ -419,6 +429,7 @@ static void __init reserve_initrd(void) /* All are mapped, easy case */ initrd_start = ramdisk_image + PAGE_OFFSET; initrd_end = initrd_start + ramdisk_size; + update_mc_saved_data(0); return; }