* [PATCH 0/2] x86/microcode/amd: early loading fixes
@ 2013-06-05 20:13 Jacob Shin
2013-06-05 20:13 ` [PATCH 1/2] x86/microcode/amd: make find_ucode_in_initrd() __init Jacob Shin
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Jacob Shin @ 2013-06-05 20:13 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Ingo Molnar, Thomas Gleixner, Yinghai Lu,
Henrique de Moraes Holschuh, x86, linux-kernel, Jacob Shin
This patchset addreses two problems with early loading on AMD.
First, feedback from Yinghai that find_ucode_in_initrd() should be
marked __init:
https://lkml.org/lkml/2013/6/4/695
And second, feedback from Henrique that Intel early loading supports
multiple microcode firmware concatenated together, whereas the current
AMD implementation lacks this support:
https://lkml.org/lkml/2013/5/31/4
Jacob Shin (2):
x86/microcode/amd: make find_ucode_in_initrd() __init
x86/microcode/amd: allow multiple families' bin files appended
together
arch/x86/kernel/microcode_amd_early.c | 148 ++++++++++++++++++++++++---------
1 file changed, 110 insertions(+), 38 deletions(-)
--
1.7.9.5
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 1/2] x86/microcode/amd: make find_ucode_in_initrd() __init 2013-06-05 20:13 [PATCH 0/2] x86/microcode/amd: early loading fixes Jacob Shin @ 2013-06-05 20:13 ` Jacob Shin 2013-06-05 22:05 ` Yinghai Lu 2013-06-12 20:47 ` [tip:x86/microcode] x86, microcode, amd: Make " tip-bot for Jacob Shin 2013-06-05 20:13 ` [PATCH 2/2] x86/microcode/amd: allow multiple families' bin files appended together Jacob Shin 2013-06-05 22:18 ` [PATCH 0/2] x86/microcode/amd: early loading fixes Borislav Petkov 2 siblings, 2 replies; 9+ messages in thread From: Jacob Shin @ 2013-06-05 20:13 UTC (permalink / raw) To: H. Peter Anvin Cc: Ingo Molnar, Thomas Gleixner, Yinghai Lu, Henrique de Moraes Holschuh, x86, linux-kernel, Jacob Shin Change find_ucode_in_initrd() to __init and only let BSP call it during cold boot. This is the right thing to do because only BSP will see initrd loaded by the boot loader. APs will offset into initrd_start to find the microcode patch binary. Reported-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Jacob Shin <jacob.shin@amd.com> --- arch/x86/kernel/microcode_amd_early.c | 98 +++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 30 deletions(-) diff --git a/arch/x86/kernel/microcode_amd_early.c b/arch/x86/kernel/microcode_amd_early.c index 9618805..7db1e16 100644 --- a/arch/x86/kernel/microcode_amd_early.c +++ b/arch/x86/kernel/microcode_amd_early.c @@ -9,6 +9,7 @@ */ #include <linux/earlycpio.h> +#include <linux/initrd.h> #include <asm/cpu.h> #include <asm/setup.h> @@ -16,40 +17,59 @@ static bool ucode_loaded; static u32 ucode_new_rev; +static unsigned long ucode_offset; +static size_t ucode_size; /* * Microcode patch container file is prepended to the initrd in cpio format. * See Documentation/x86/early-microcode.txt */ -static __cpuinitdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin"; +static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin"; -static struct cpio_data __cpuinit find_ucode_in_initrd(void) +static struct cpio_data __init find_ucode_in_initrd(void) { long offset = 0; + char *path; + void *start; + size_t size; + unsigned long *uoffset; + size_t *usize; struct cpio_data cd; #ifdef CONFIG_X86_32 + struct boot_params *p; + /* * On 32-bit, early load occurs before paging is turned on so we need * to use physical addresses. */ - if (!(read_cr0() & X86_CR0_PG)) { - struct boot_params *p; - p = (struct boot_params *)__pa_nodebug(&boot_params); - cd = find_cpio_data((char *)__pa_nodebug(ucode_path), - (void *)p->hdr.ramdisk_image, p->hdr.ramdisk_size, - &offset); - } else + p = (struct boot_params *)__pa_nodebug(&boot_params); + path = (char *)__pa_nodebug(ucode_path); + start = (void *)p->hdr.ramdisk_image; + size = p->hdr.ramdisk_size; + uoffset = (unsigned long *)__pa_nodebug(&ucode_offset); + usize = (size_t *)__pa_nodebug(&ucode_size); +#else + path = ucode_path; + start = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET); + size = boot_params.hdr.ramdisk_size; + uoffset = &ucode_offset; + usize = &ucode_size; #endif - cd = find_cpio_data(ucode_path, - (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET), - boot_params.hdr.ramdisk_size, &offset); + + cd = find_cpio_data(path, start, size, &offset); + if (!cd.data) + return cd; if (*(u32 *)cd.data != UCODE_MAGIC) { cd.data = NULL; cd.size = 0; + return cd; } + *uoffset = (u8 *)cd.data - (u8 *)start; + *usize = cd.size; + return cd; } @@ -62,9 +82,8 @@ static struct cpio_data __cpuinit find_ucode_in_initrd(void) * load_microcode_amd() to save equivalent cpu table and microcode patches in * kernel heap memory. */ -static void __cpuinit apply_ucode_in_initrd(void) +static void __cpuinit apply_ucode_in_initrd(void *ucode, size_t size) { - struct cpio_data cd; struct equiv_cpu_entry *eq; u32 *header; u8 *data; @@ -78,12 +97,9 @@ static void __cpuinit apply_ucode_in_initrd(void) #else new_rev = &ucode_new_rev; #endif - cd = find_ucode_in_initrd(); - if (!cd.data) - return; - data = cd.data; - left = cd.size; + data = ucode; + left = size; header = (u32 *)data; /* find equiv cpu table */ @@ -129,7 +145,11 @@ static void __cpuinit apply_ucode_in_initrd(void) void __init load_ucode_amd_bsp(void) { - apply_ucode_in_initrd(); + struct cpio_data cd = find_ucode_in_initrd(); + if (!cd.data) + return; + + apply_ucode_in_initrd(cd.data, cd.size); } #ifdef CONFIG_X86_32 @@ -145,12 +165,25 @@ u8 amd_bsp_mpb[MPB_MAX_SIZE]; void __cpuinit load_ucode_amd_ap(void) { struct microcode_amd *mc; + unsigned long *initrd; + unsigned long *uoffset; + size_t *usize; + void *ucode; mc = (struct microcode_amd *)__pa_nodebug(amd_bsp_mpb); - if (mc->hdr.patch_id && mc->hdr.processor_rev_id) + if (mc->hdr.patch_id && mc->hdr.processor_rev_id) { __apply_microcode_amd(mc); - else - apply_ucode_in_initrd(); + return; + } + + initrd = (unsigned long *)__pa_nodebug(&initrd_start); + uoffset = (unsigned long *)__pa_nodebug(&ucode_offset); + usize = (size_t *)__pa_nodebug(&ucode_size); + if (!*usize) + return; + + ucode = (void *)((unsigned long)__pa_nodebug(*initrd) + *uoffset); + apply_ucode_in_initrd(ucode, *usize); } static void __init collect_cpu_sig_on_bsp(void *arg) @@ -181,8 +214,13 @@ void __cpuinit load_ucode_amd_ap(void) collect_cpu_info_amd_early(&cpu_data(cpu), ucode_cpu_info + cpu); if (cpu && !ucode_loaded) { - struct cpio_data cd = find_ucode_in_initrd(); - if (load_microcode_amd(0, cd.data, cd.size) != UCODE_OK) + void *ucode; + + if (!ucode_size) + return; + + ucode = (void *)(initrd_start + ucode_offset); + if (load_microcode_amd(0, ucode, ucode_size) != UCODE_OK) return; ucode_loaded = true; } @@ -194,7 +232,7 @@ void __cpuinit load_ucode_amd_ap(void) int __init save_microcode_in_initrd_amd(void) { enum ucode_state ret; - struct cpio_data cd; + void *ucode; #ifdef CONFIG_X86_32 unsigned int bsp = boot_cpu_data.cpu_index; struct ucode_cpu_info *uci = ucode_cpu_info + bsp; @@ -209,11 +247,11 @@ int __init save_microcode_in_initrd_amd(void) if (ucode_loaded) return 0; - cd = find_ucode_in_initrd(); - if (!cd.data) - return -EINVAL; + if (!ucode_size) + return 0; - ret = load_microcode_amd(0, cd.data, cd.size); + ucode = (void *)(initrd_start + ucode_offset); + ret = load_microcode_amd(0, ucode, ucode_size); if (ret != UCODE_OK) return -EINVAL; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] x86/microcode/amd: make find_ucode_in_initrd() __init 2013-06-05 20:13 ` [PATCH 1/2] x86/microcode/amd: make find_ucode_in_initrd() __init Jacob Shin @ 2013-06-05 22:05 ` Yinghai Lu 2013-06-12 20:47 ` [tip:x86/microcode] x86, microcode, amd: Make " tip-bot for Jacob Shin 1 sibling, 0 replies; 9+ messages in thread From: Yinghai Lu @ 2013-06-05 22:05 UTC (permalink / raw) To: Jacob Shin Cc: H. Peter Anvin, Ingo Molnar, Thomas Gleixner, Henrique de Moraes Holschuh, the arch/x86 maintainers, Linux Kernel Mailing List On Wed, Jun 5, 2013 at 1:13 PM, Jacob Shin <jacob.shin@amd.com> wrote: > Change find_ucode_in_initrd() to __init and only let BSP call it > during cold boot. This is the right thing to do because only BSP will > see initrd loaded by the boot loader. APs will offset into > initrd_start to find the microcode patch binary. > > Reported-by: Yinghai Lu <yinghai@kernel.org> > Signed-off-by: Jacob Shin <jacob.shin@amd.com> > --- > arch/x86/kernel/microcode_amd_early.c | 98 +++++++++++++++++++++++---------- > 1 file changed, 68 insertions(+), 30 deletions(-) > > diff --git a/arch/x86/kernel/microcode_amd_early.c b/arch/x86/kernel/microcode_amd_early.c > index 9618805..7db1e16 100644 > --- a/arch/x86/kernel/microcode_amd_early.c > +++ b/arch/x86/kernel/microcode_amd_early.c > @@ -9,6 +9,7 @@ > */ > > #include <linux/earlycpio.h> > +#include <linux/initrd.h> > > #include <asm/cpu.h> > #include <asm/setup.h> > @@ -16,40 +17,59 @@ > > static bool ucode_loaded; > static u32 ucode_new_rev; > +static unsigned long ucode_offset; > +static size_t ucode_size; > > /* > * Microcode patch container file is prepended to the initrd in cpio format. > * See Documentation/x86/early-microcode.txt > */ > -static __cpuinitdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin"; > +static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin"; > > -static struct cpio_data __cpuinit find_ucode_in_initrd(void) > +static struct cpio_data __init find_ucode_in_initrd(void) > { > long offset = 0; > + char *path; > + void *start; > + size_t size; > + unsigned long *uoffset; > + size_t *usize; > struct cpio_data cd; > > #ifdef CONFIG_X86_32 > + struct boot_params *p; > + > /* > * On 32-bit, early load occurs before paging is turned on so we need > * to use physical addresses. > */ > - if (!(read_cr0() & X86_CR0_PG)) { > - struct boot_params *p; > - p = (struct boot_params *)__pa_nodebug(&boot_params); > - cd = find_cpio_data((char *)__pa_nodebug(ucode_path), > - (void *)p->hdr.ramdisk_image, p->hdr.ramdisk_size, > - &offset); > - } else > + p = (struct boot_params *)__pa_nodebug(&boot_params); > + path = (char *)__pa_nodebug(ucode_path); > + start = (void *)p->hdr.ramdisk_image; > + size = p->hdr.ramdisk_size; > + uoffset = (unsigned long *)__pa_nodebug(&ucode_offset); > + usize = (size_t *)__pa_nodebug(&ucode_size); > +#else > + path = ucode_path; > + start = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET); > + size = boot_params.hdr.ramdisk_size; > + uoffset = &ucode_offset; > + usize = &ucode_size; > #endif > - cd = find_cpio_data(ucode_path, > - (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET), > - boot_params.hdr.ramdisk_size, &offset); > + > + cd = find_cpio_data(path, start, size, &offset); > + if (!cd.data) > + return cd; > > if (*(u32 *)cd.data != UCODE_MAGIC) { > cd.data = NULL; > cd.size = 0; > + return cd; > } > > + *uoffset = (u8 *)cd.data - (u8 *)start; > + *usize = cd.size; > + > return cd; > } > > @@ -62,9 +82,8 @@ static struct cpio_data __cpuinit find_ucode_in_initrd(void) > * load_microcode_amd() to save equivalent cpu table and microcode patches in > * kernel heap memory. > */ > -static void __cpuinit apply_ucode_in_initrd(void) > +static void __cpuinit apply_ucode_in_initrd(void *ucode, size_t size) > { > - struct cpio_data cd; > struct equiv_cpu_entry *eq; > u32 *header; > u8 *data; > @@ -78,12 +97,9 @@ static void __cpuinit apply_ucode_in_initrd(void) > #else > new_rev = &ucode_new_rev; > #endif > - cd = find_ucode_in_initrd(); > - if (!cd.data) > - return; > > - data = cd.data; > - left = cd.size; > + data = ucode; > + left = size; > header = (u32 *)data; > > /* find equiv cpu table */ > @@ -129,7 +145,11 @@ static void __cpuinit apply_ucode_in_initrd(void) > > void __init load_ucode_amd_bsp(void) > { > - apply_ucode_in_initrd(); > + struct cpio_data cd = find_ucode_in_initrd(); > + if (!cd.data) > + return; > + > + apply_ucode_in_initrd(cd.data, cd.size); > } > > #ifdef CONFIG_X86_32 > @@ -145,12 +165,25 @@ u8 amd_bsp_mpb[MPB_MAX_SIZE]; > void __cpuinit load_ucode_amd_ap(void) > { > struct microcode_amd *mc; > + unsigned long *initrd; > + unsigned long *uoffset; > + size_t *usize; > + void *ucode; > > mc = (struct microcode_amd *)__pa_nodebug(amd_bsp_mpb); > - if (mc->hdr.patch_id && mc->hdr.processor_rev_id) > + if (mc->hdr.patch_id && mc->hdr.processor_rev_id) { > __apply_microcode_amd(mc); > - else > - apply_ucode_in_initrd(); > + return; > + } > + may need to check "if (!initrd_start)" here. > + initrd = (unsigned long *)__pa_nodebug(&initrd_start); > + uoffset = (unsigned long *)__pa_nodebug(&ucode_offset); > + usize = (size_t *)__pa_nodebug(&ucode_size); could use __pa directly here. > + if (!*usize) > + return; > + > + ucode = (void *)((unsigned long)__pa_nodebug(*initrd) + *uoffset); same. > + apply_ucode_in_initrd(ucode, *usize); > } > > static void __init collect_cpu_sig_on_bsp(void *arg) > @@ -181,8 +214,13 @@ void __cpuinit load_ucode_amd_ap(void) > collect_cpu_info_amd_early(&cpu_data(cpu), ucode_cpu_info + cpu); > > if (cpu && !ucode_loaded) { > - struct cpio_data cd = find_ucode_in_initrd(); > - if (load_microcode_amd(0, cd.data, cd.size) != UCODE_OK) > + void *ucode; > + > + if (!ucode_size) > + return; > + > + ucode = (void *)(initrd_start + ucode_offset); > + if (load_microcode_amd(0, ucode, ucode_size) != UCODE_OK) > return; > ucode_loaded = true; > } > @@ -194,7 +232,7 @@ void __cpuinit load_ucode_amd_ap(void) > int __init save_microcode_in_initrd_amd(void) > { > enum ucode_state ret; > - struct cpio_data cd; > + void *ucode; > #ifdef CONFIG_X86_32 > unsigned int bsp = boot_cpu_data.cpu_index; > struct ucode_cpu_info *uci = ucode_cpu_info + bsp; > @@ -209,11 +247,11 @@ int __init save_microcode_in_initrd_amd(void) > if (ucode_loaded) > return 0; > > - cd = find_ucode_in_initrd(); > - if (!cd.data) > - return -EINVAL; > + if (!ucode_size) > + return 0; > > - ret = load_microcode_amd(0, cd.data, cd.size); > + ucode = (void *)(initrd_start + ucode_offset); > + ret = load_microcode_amd(0, ucode, ucode_size); > if (ret != UCODE_OK) > return -EINVAL; > > -- > 1.7.9.5 > > ^ permalink raw reply [flat|nested] 9+ messages in thread
* [tip:x86/microcode] x86, microcode, amd: Make find_ucode_in_initrd() __init 2013-06-05 20:13 ` [PATCH 1/2] x86/microcode/amd: make find_ucode_in_initrd() __init Jacob Shin 2013-06-05 22:05 ` Yinghai Lu @ 2013-06-12 20:47 ` tip-bot for Jacob Shin 1 sibling, 0 replies; 9+ messages in thread From: tip-bot for Jacob Shin @ 2013-06-12 20:47 UTC (permalink / raw) To: linux-tip-commits Cc: linux-kernel, hpa, mingo, yinghai, fenghua.yu, jacob.shin, tglx, hpa Commit-ID: 275bbe2e299f1820ec8faa443d689469a9e6ecc5 Gitweb: http://git.kernel.org/tip/275bbe2e299f1820ec8faa443d689469a9e6ecc5 Author: Jacob Shin <jacob.shin@amd.com> AuthorDate: Wed, 5 Jun 2013 15:13:55 -0500 Committer: H. Peter Anvin <hpa@linux.intel.com> CommitDate: Wed, 5 Jun 2013 13:56:47 -0700 x86, microcode, amd: Make find_ucode_in_initrd() __init Change find_ucode_in_initrd() to __init and only let BSP call it during cold boot. This is the right thing to do because only BSP will see initrd loaded by the boot loader. APs will offset into initrd_start to find the microcode patch binary. Reported-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Jacob Shin <jacob.shin@amd.com> Link: http://lkml.kernel.org/r/1370463236-2115-2-git-send-email-jacob.shin@amd.com Cc: Fenghua Yu <fenghua.yu@intel.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> --- arch/x86/kernel/microcode_amd_early.c | 98 ++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 30 deletions(-) diff --git a/arch/x86/kernel/microcode_amd_early.c b/arch/x86/kernel/microcode_amd_early.c index 9618805..7db1e16 100644 --- a/arch/x86/kernel/microcode_amd_early.c +++ b/arch/x86/kernel/microcode_amd_early.c @@ -9,6 +9,7 @@ */ #include <linux/earlycpio.h> +#include <linux/initrd.h> #include <asm/cpu.h> #include <asm/setup.h> @@ -16,40 +17,59 @@ static bool ucode_loaded; static u32 ucode_new_rev; +static unsigned long ucode_offset; +static size_t ucode_size; /* * Microcode patch container file is prepended to the initrd in cpio format. * See Documentation/x86/early-microcode.txt */ -static __cpuinitdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin"; +static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin"; -static struct cpio_data __cpuinit find_ucode_in_initrd(void) +static struct cpio_data __init find_ucode_in_initrd(void) { long offset = 0; + char *path; + void *start; + size_t size; + unsigned long *uoffset; + size_t *usize; struct cpio_data cd; #ifdef CONFIG_X86_32 + struct boot_params *p; + /* * On 32-bit, early load occurs before paging is turned on so we need * to use physical addresses. */ - if (!(read_cr0() & X86_CR0_PG)) { - struct boot_params *p; - p = (struct boot_params *)__pa_nodebug(&boot_params); - cd = find_cpio_data((char *)__pa_nodebug(ucode_path), - (void *)p->hdr.ramdisk_image, p->hdr.ramdisk_size, - &offset); - } else + p = (struct boot_params *)__pa_nodebug(&boot_params); + path = (char *)__pa_nodebug(ucode_path); + start = (void *)p->hdr.ramdisk_image; + size = p->hdr.ramdisk_size; + uoffset = (unsigned long *)__pa_nodebug(&ucode_offset); + usize = (size_t *)__pa_nodebug(&ucode_size); +#else + path = ucode_path; + start = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET); + size = boot_params.hdr.ramdisk_size; + uoffset = &ucode_offset; + usize = &ucode_size; #endif - cd = find_cpio_data(ucode_path, - (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET), - boot_params.hdr.ramdisk_size, &offset); + + cd = find_cpio_data(path, start, size, &offset); + if (!cd.data) + return cd; if (*(u32 *)cd.data != UCODE_MAGIC) { cd.data = NULL; cd.size = 0; + return cd; } + *uoffset = (u8 *)cd.data - (u8 *)start; + *usize = cd.size; + return cd; } @@ -62,9 +82,8 @@ static struct cpio_data __cpuinit find_ucode_in_initrd(void) * load_microcode_amd() to save equivalent cpu table and microcode patches in * kernel heap memory. */ -static void __cpuinit apply_ucode_in_initrd(void) +static void __cpuinit apply_ucode_in_initrd(void *ucode, size_t size) { - struct cpio_data cd; struct equiv_cpu_entry *eq; u32 *header; u8 *data; @@ -78,12 +97,9 @@ static void __cpuinit apply_ucode_in_initrd(void) #else new_rev = &ucode_new_rev; #endif - cd = find_ucode_in_initrd(); - if (!cd.data) - return; - data = cd.data; - left = cd.size; + data = ucode; + left = size; header = (u32 *)data; /* find equiv cpu table */ @@ -129,7 +145,11 @@ static void __cpuinit apply_ucode_in_initrd(void) void __init load_ucode_amd_bsp(void) { - apply_ucode_in_initrd(); + struct cpio_data cd = find_ucode_in_initrd(); + if (!cd.data) + return; + + apply_ucode_in_initrd(cd.data, cd.size); } #ifdef CONFIG_X86_32 @@ -145,12 +165,25 @@ u8 amd_bsp_mpb[MPB_MAX_SIZE]; void __cpuinit load_ucode_amd_ap(void) { struct microcode_amd *mc; + unsigned long *initrd; + unsigned long *uoffset; + size_t *usize; + void *ucode; mc = (struct microcode_amd *)__pa_nodebug(amd_bsp_mpb); - if (mc->hdr.patch_id && mc->hdr.processor_rev_id) + if (mc->hdr.patch_id && mc->hdr.processor_rev_id) { __apply_microcode_amd(mc); - else - apply_ucode_in_initrd(); + return; + } + + initrd = (unsigned long *)__pa_nodebug(&initrd_start); + uoffset = (unsigned long *)__pa_nodebug(&ucode_offset); + usize = (size_t *)__pa_nodebug(&ucode_size); + if (!*usize) + return; + + ucode = (void *)((unsigned long)__pa_nodebug(*initrd) + *uoffset); + apply_ucode_in_initrd(ucode, *usize); } static void __init collect_cpu_sig_on_bsp(void *arg) @@ -181,8 +214,13 @@ void __cpuinit load_ucode_amd_ap(void) collect_cpu_info_amd_early(&cpu_data(cpu), ucode_cpu_info + cpu); if (cpu && !ucode_loaded) { - struct cpio_data cd = find_ucode_in_initrd(); - if (load_microcode_amd(0, cd.data, cd.size) != UCODE_OK) + void *ucode; + + if (!ucode_size) + return; + + ucode = (void *)(initrd_start + ucode_offset); + if (load_microcode_amd(0, ucode, ucode_size) != UCODE_OK) return; ucode_loaded = true; } @@ -194,7 +232,7 @@ void __cpuinit load_ucode_amd_ap(void) int __init save_microcode_in_initrd_amd(void) { enum ucode_state ret; - struct cpio_data cd; + void *ucode; #ifdef CONFIG_X86_32 unsigned int bsp = boot_cpu_data.cpu_index; struct ucode_cpu_info *uci = ucode_cpu_info + bsp; @@ -209,11 +247,11 @@ int __init save_microcode_in_initrd_amd(void) if (ucode_loaded) return 0; - cd = find_ucode_in_initrd(); - if (!cd.data) - return -EINVAL; + if (!ucode_size) + return 0; - ret = load_microcode_amd(0, cd.data, cd.size); + ucode = (void *)(initrd_start + ucode_offset); + ret = load_microcode_amd(0, ucode, ucode_size); if (ret != UCODE_OK) return -EINVAL; ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] x86/microcode/amd: allow multiple families' bin files appended together 2013-06-05 20:13 [PATCH 0/2] x86/microcode/amd: early loading fixes Jacob Shin 2013-06-05 20:13 ` [PATCH 1/2] x86/microcode/amd: make find_ucode_in_initrd() __init Jacob Shin @ 2013-06-05 20:13 ` Jacob Shin 2013-06-12 20:47 ` [tip:x86/microcode] x86, microcode, amd: Allow " tip-bot for Jacob Shin 2013-06-05 22:18 ` [PATCH 0/2] x86/microcode/amd: early loading fixes Borislav Petkov 2 siblings, 1 reply; 9+ messages in thread From: Jacob Shin @ 2013-06-05 20:13 UTC (permalink / raw) To: H. Peter Anvin Cc: Ingo Molnar, Thomas Gleixner, Yinghai Lu, Henrique de Moraes Holschuh, x86, linux-kernel, Jacob Shin Add support for parsing through multiple families' microcode patch container binary files appended together when early loading. This is already supported on Intel. Reported-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: Jacob Shin <jacob.shin@amd.com> --- arch/x86/kernel/microcode_amd_early.c | 50 +++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/microcode_amd_early.c b/arch/x86/kernel/microcode_amd_early.c index 7db1e16..4c593c2 100644 --- a/arch/x86/kernel/microcode_amd_early.c +++ b/arch/x86/kernel/microcode_amd_early.c @@ -87,15 +87,21 @@ static void __cpuinit apply_ucode_in_initrd(void *ucode, size_t size) struct equiv_cpu_entry *eq; u32 *header; u8 *data; - u16 eq_id; + u16 eq_id = 0; int offset, left; - u32 rev, dummy; + u32 rev, eax; u32 *new_rev; + unsigned long *uoffset; + size_t *usize; #ifdef CONFIG_X86_32 new_rev = (u32 *)__pa_nodebug(&ucode_new_rev); + uoffset = (unsigned long *)__pa_nodebug(&ucode_offset); + usize = (size_t *)__pa_nodebug(&ucode_size); #else new_rev = &ucode_new_rev; + uoffset = &ucode_offset; + usize = &ucode_size; #endif data = ucode; @@ -108,18 +114,46 @@ static void __cpuinit apply_ucode_in_initrd(void *ucode, size_t size) header[2] == 0) /* size */ return; - eq = (struct equiv_cpu_entry *)(data + CONTAINER_HDR_SZ); - offset = header[2] + CONTAINER_HDR_SZ; - data += offset; - left -= offset; + eax = cpuid_eax(0x00000001); + + while (left > 0) { + eq = (struct equiv_cpu_entry *)(data + CONTAINER_HDR_SZ); + + offset = header[2] + CONTAINER_HDR_SZ; + data += offset; + left -= offset; + + eq_id = find_equiv_id(eq, eax); + if (eq_id) + break; + + /* + * support multiple container files appended together. if this + * one does not have a matching equivalent cpu entry, we fast + * forward to the next container file. + */ + while (left > 0) { + header = (u32 *)data; + if (header[0] == UCODE_MAGIC && + header[1] == UCODE_EQUIV_CPU_TABLE_TYPE) + break; + + offset = header[1] + SECTION_HDR_SIZE; + data += offset; + left -= offset; + } + + offset = data - (u8 *)ucode; + *uoffset += offset; + *usize -= offset; + } - eq_id = find_equiv_id(eq, cpuid_eax(0x00000001)); if (!eq_id) return; /* find ucode and update if needed */ - rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); + rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax); while (left > 0) { struct microcode_amd *mc; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [tip:x86/microcode] x86, microcode, amd: Allow multiple families' bin files appended together 2013-06-05 20:13 ` [PATCH 2/2] x86/microcode/amd: allow multiple families' bin files appended together Jacob Shin @ 2013-06-12 20:47 ` tip-bot for Jacob Shin 0 siblings, 0 replies; 9+ messages in thread From: tip-bot for Jacob Shin @ 2013-06-12 20:47 UTC (permalink / raw) To: linux-tip-commits; +Cc: linux-kernel, hmh, hpa, mingo, jacob.shin, tglx, hpa Commit-ID: cd1c32ca969ebfd65e61312c988223bb14f09c2e Gitweb: http://git.kernel.org/tip/cd1c32ca969ebfd65e61312c988223bb14f09c2e Author: Jacob Shin <jacob.shin@amd.com> AuthorDate: Wed, 5 Jun 2013 15:13:56 -0500 Committer: H. Peter Anvin <hpa@linux.intel.com> CommitDate: Wed, 5 Jun 2013 13:56:55 -0700 x86, microcode, amd: Allow multiple families' bin files appended together Add support for parsing through multiple families' microcode patch container binary files appended together when early loading. This is already supported on Intel. Reported-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: Jacob Shin <jacob.shin@amd.com> Link: http://lkml.kernel.org/r/1370463236-2115-3-git-send-email-jacob.shin@amd.com Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> --- arch/x86/kernel/microcode_amd_early.c | 50 +++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/microcode_amd_early.c b/arch/x86/kernel/microcode_amd_early.c index 7db1e16..4c593c2 100644 --- a/arch/x86/kernel/microcode_amd_early.c +++ b/arch/x86/kernel/microcode_amd_early.c @@ -87,15 +87,21 @@ static void __cpuinit apply_ucode_in_initrd(void *ucode, size_t size) struct equiv_cpu_entry *eq; u32 *header; u8 *data; - u16 eq_id; + u16 eq_id = 0; int offset, left; - u32 rev, dummy; + u32 rev, eax; u32 *new_rev; + unsigned long *uoffset; + size_t *usize; #ifdef CONFIG_X86_32 new_rev = (u32 *)__pa_nodebug(&ucode_new_rev); + uoffset = (unsigned long *)__pa_nodebug(&ucode_offset); + usize = (size_t *)__pa_nodebug(&ucode_size); #else new_rev = &ucode_new_rev; + uoffset = &ucode_offset; + usize = &ucode_size; #endif data = ucode; @@ -108,18 +114,46 @@ static void __cpuinit apply_ucode_in_initrd(void *ucode, size_t size) header[2] == 0) /* size */ return; - eq = (struct equiv_cpu_entry *)(data + CONTAINER_HDR_SZ); - offset = header[2] + CONTAINER_HDR_SZ; - data += offset; - left -= offset; + eax = cpuid_eax(0x00000001); + + while (left > 0) { + eq = (struct equiv_cpu_entry *)(data + CONTAINER_HDR_SZ); + + offset = header[2] + CONTAINER_HDR_SZ; + data += offset; + left -= offset; + + eq_id = find_equiv_id(eq, eax); + if (eq_id) + break; + + /* + * support multiple container files appended together. if this + * one does not have a matching equivalent cpu entry, we fast + * forward to the next container file. + */ + while (left > 0) { + header = (u32 *)data; + if (header[0] == UCODE_MAGIC && + header[1] == UCODE_EQUIV_CPU_TABLE_TYPE) + break; + + offset = header[1] + SECTION_HDR_SIZE; + data += offset; + left -= offset; + } + + offset = data - (u8 *)ucode; + *uoffset += offset; + *usize -= offset; + } - eq_id = find_equiv_id(eq, cpuid_eax(0x00000001)); if (!eq_id) return; /* find ucode and update if needed */ - rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); + rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax); while (left > 0) { struct microcode_amd *mc; ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 0/2] x86/microcode/amd: early loading fixes 2013-06-05 20:13 [PATCH 0/2] x86/microcode/amd: early loading fixes Jacob Shin 2013-06-05 20:13 ` [PATCH 1/2] x86/microcode/amd: make find_ucode_in_initrd() __init Jacob Shin 2013-06-05 20:13 ` [PATCH 2/2] x86/microcode/amd: allow multiple families' bin files appended together Jacob Shin @ 2013-06-05 22:18 ` Borislav Petkov 2013-06-05 23:01 ` H. Peter Anvin 2013-06-06 14:28 ` Jacob Shin 2 siblings, 2 replies; 9+ messages in thread From: Borislav Petkov @ 2013-06-05 22:18 UTC (permalink / raw) To: Jacob Shin Cc: H. Peter Anvin, Ingo Molnar, Thomas Gleixner, Yinghai Lu, Henrique de Moraes Holschuh, x86, linux-kernel, Andreas Herrmann On Wed, Jun 05, 2013 at 03:13:54PM -0500, Jacob Shin wrote: > This patchset addreses two problems with early loading on AMD. It would be nice if, in the future, you put the maintainers of this driver to CC. Unless you're volunteering up for maintaining it... -- Regards/Gruss, Boris. Sent from a fat crate under my desk. Formatting is fine. -- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/2] x86/microcode/amd: early loading fixes 2013-06-05 22:18 ` [PATCH 0/2] x86/microcode/amd: early loading fixes Borislav Petkov @ 2013-06-05 23:01 ` H. Peter Anvin 2013-06-06 14:28 ` Jacob Shin 1 sibling, 0 replies; 9+ messages in thread From: H. Peter Anvin @ 2013-06-05 23:01 UTC (permalink / raw) To: Borislav Petkov Cc: Jacob Shin, Ingo Molnar, Thomas Gleixner, Yinghai Lu, Henrique de Moraes Holschuh, x86, linux-kernel, Andreas Herrmann On 06/05/2013 03:18 PM, Borislav Petkov wrote: > On Wed, Jun 05, 2013 at 03:13:54PM -0500, Jacob Shin wrote: >> This patchset addreses two problems with early loading on AMD. > > It would be nice if, in the future, you put the maintainers of this > driver to CC. > > Unless you're volunteering up for maintaining it... > Indeed. My bad for not adding all in, too. -hpa ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/2] x86/microcode/amd: early loading fixes 2013-06-05 22:18 ` [PATCH 0/2] x86/microcode/amd: early loading fixes Borislav Petkov 2013-06-05 23:01 ` H. Peter Anvin @ 2013-06-06 14:28 ` Jacob Shin 1 sibling, 0 replies; 9+ messages in thread From: Jacob Shin @ 2013-06-06 14:28 UTC (permalink / raw) To: Borislav Petkov Cc: H. Peter Anvin, Ingo Molnar, Thomas Gleixner, Yinghai Lu, Henrique de Moraes Holschuh, x86, linux-kernel, Andreas Herrmann On Thu, Jun 06, 2013 at 12:18:33AM +0200, Borislav Petkov wrote: > On Wed, Jun 05, 2013 at 03:13:54PM -0500, Jacob Shin wrote: > > This patchset addreses two problems with early loading on AMD. > > It would be nice if, in the future, you put the maintainers of this > driver to CC. Oops, sorry about that, I meant to do so, will do on V2 today. > > Unless you're volunteering up for maintaining it... > > -- > Regards/Gruss, > Boris. > > Sent from a fat crate under my desk. Formatting is fine. > -- > ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-06-12 20:48 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-06-05 20:13 [PATCH 0/2] x86/microcode/amd: early loading fixes Jacob Shin 2013-06-05 20:13 ` [PATCH 1/2] x86/microcode/amd: make find_ucode_in_initrd() __init Jacob Shin 2013-06-05 22:05 ` Yinghai Lu 2013-06-12 20:47 ` [tip:x86/microcode] x86, microcode, amd: Make " tip-bot for Jacob Shin 2013-06-05 20:13 ` [PATCH 2/2] x86/microcode/amd: allow multiple families' bin files appended together Jacob Shin 2013-06-12 20:47 ` [tip:x86/microcode] x86, microcode, amd: Allow " tip-bot for Jacob Shin 2013-06-05 22:18 ` [PATCH 0/2] x86/microcode/amd: early loading fixes Borislav Petkov 2013-06-05 23:01 ` H. Peter Anvin 2013-06-06 14:28 ` Jacob Shin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox