Re: [PATCH 29/42] x86: Find correct 64 bit ramdisk address for microcode early update
From: Kees Cook
Date: Tue Jul 07 2015 - 19:08:58 EST
On Tue, Jul 7, 2015 at 1:20 PM, Yinghai Lu <yinghai@xxxxxxxxxx> wrote:
> When using kexec with 64bit kernel, bzImage and ramdisk could be
> loaded above 4G. We need this to get correct ramdisk adress.
>
> Make get_ramdisk_image() global and use it for early microcode updating.
This looks correct, thanks!
Acked-by: Kees Cook <keescook@xxxxxxxxxxxx>
-Kees
>
> -v2: update changelog.
>
> Signed-off-by: Yinghai Lu <yinghai@xxxxxxxxxx>
> ---
> arch/x86/include/asm/setup.h | 3 +++
> arch/x86/kernel/cpu/microcode/amd_early.c | 10 +++++-----
> arch/x86/kernel/cpu/microcode/intel_early.c | 8 ++++----
> arch/x86/kernel/setup.c | 28 ++++++++++++++--------------
> 4 files changed, 26 insertions(+), 23 deletions(-)
>
> diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
> index 3e5aa41..496515b 100644
> --- a/arch/x86/include/asm/setup.h
> +++ b/arch/x86/include/asm/setup.h
> @@ -119,6 +119,9 @@ void *extend_brk(size_t size, size_t align);
> RESERVE_BRK(name, sizeof(type) * entries)
>
> extern void probe_roms(void);
> +u64 get_ramdisk_image(struct boot_params *bp);
> +u64 get_ramdisk_size(struct boot_params *bp);
> +
> #ifdef __i386__
>
> asmlinkage void __init i386_start_kernel(void);
> diff --git a/arch/x86/kernel/cpu/microcode/amd_early.c b/arch/x86/kernel/cpu/microcode/amd_early.c
> index e8a215a..4c579c7 100644
> --- a/arch/x86/kernel/cpu/microcode/amd_early.c
> +++ b/arch/x86/kernel/cpu/microcode/amd_early.c
> @@ -51,12 +51,12 @@ static struct cpio_data __init find_ucode_in_initrd(void)
> */
> 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;
> + start = (void *)(unsigned long)get_ramdisk_image(p);
> + size = get_ramdisk_size(p);
> #else
> path = ucode_path;
> - start = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET);
> - size = boot_params.hdr.ramdisk_size;
> + start = (void *)(get_ramdisk_image(&boot_params) + PAGE_OFFSET);
> + size = get_ramdisk_size(&boot_params);
> #endif
>
> return find_cpio_data(path, start, size, &offset);
> @@ -396,7 +396,7 @@ int __init save_microcode_in_initrd_amd(void)
> */
> if (relocated_ramdisk)
> container = (u8 *)(__va(relocated_ramdisk) +
> - (cont - boot_params.hdr.ramdisk_image));
> + (cont - get_ramdisk_size(&boot_params)));
> else
> container = cont_va;
>
> diff --git a/arch/x86/kernel/cpu/microcode/intel_early.c b/arch/x86/kernel/cpu/microcode/intel_early.c
> index 8187b72..c85dcb2 100644
> --- a/arch/x86/kernel/cpu/microcode/intel_early.c
> +++ b/arch/x86/kernel/cpu/microcode/intel_early.c
> @@ -736,16 +736,16 @@ void __init load_ucode_intel_bsp(void)
> struct boot_params *p;
>
> p = (struct boot_params *)__pa_nodebug(&boot_params);
> - start = p->hdr.ramdisk_image;
> - size = p->hdr.ramdisk_size;
> + start = get_ramdisk_image(p);
> + size = get_ramdisk_size(p);
>
> _load_ucode_intel_bsp(
> (struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
> (unsigned long *)__pa_nodebug(&mc_saved_in_initrd),
> start, size);
> #else
> - start = boot_params.hdr.ramdisk_image + PAGE_OFFSET;
> - size = boot_params.hdr.ramdisk_size;
> + start = get_ramdisk_image(&boot_params) + PAGE_OFFSET;
> + size = get_ramdisk_size(&boot_params);
>
> _load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd, start, size);
> #endif
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 80f874b..2d808e6 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -300,19 +300,19 @@ u64 relocated_ramdisk;
>
> #ifdef CONFIG_BLK_DEV_INITRD
>
> -static u64 __init get_ramdisk_image(void)
> +u64 __init get_ramdisk_image(struct boot_params *bp)
> {
> - u64 ramdisk_image = boot_params.hdr.ramdisk_image;
> + u64 ramdisk_image = bp->hdr.ramdisk_image;
>
> - ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;
> + ramdisk_image |= (u64)bp->ext_ramdisk_image << 32;
>
> return ramdisk_image;
> }
> -static u64 __init get_ramdisk_size(void)
> +u64 __init get_ramdisk_size(struct boot_params *bp)
> {
> - u64 ramdisk_size = boot_params.hdr.ramdisk_size;
> + u64 ramdisk_size = bp->hdr.ramdisk_size;
>
> - ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;
> + ramdisk_size |= (u64)bp->ext_ramdisk_size << 32;
>
> return ramdisk_size;
> }
> @@ -321,8 +321,8 @@ static u64 __init get_ramdisk_size(void)
> static void __init relocate_initrd(void)
> {
> /* Assume only end is not page aligned */
> - u64 ramdisk_image = get_ramdisk_image();
> - u64 ramdisk_size = get_ramdisk_size();
> + u64 ramdisk_image = get_ramdisk_image(&boot_params);
> + u64 ramdisk_size = get_ramdisk_size(&boot_params);
> u64 area_size = PAGE_ALIGN(ramdisk_size);
> unsigned long slop, clen, mapaddr;
> char *p, *q;
> @@ -360,8 +360,8 @@ static void __init relocate_initrd(void)
> ramdisk_size -= clen;
> }
>
> - ramdisk_image = get_ramdisk_image();
> - ramdisk_size = get_ramdisk_size();
> + ramdisk_image = get_ramdisk_image(&boot_params);
> + ramdisk_size = get_ramdisk_size(&boot_params);
> printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
> " [mem %#010llx-%#010llx]\n",
> ramdisk_image, ramdisk_image + ramdisk_size - 1,
> @@ -371,8 +371,8 @@ static void __init relocate_initrd(void)
> static void __init early_reserve_initrd(void)
> {
> /* Assume only end is not page aligned */
> - u64 ramdisk_image = get_ramdisk_image();
> - u64 ramdisk_size = get_ramdisk_size();
> + u64 ramdisk_image = get_ramdisk_image(&boot_params);
> + u64 ramdisk_size = get_ramdisk_size(&boot_params);
> u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
>
> if (!boot_params.hdr.type_of_loader ||
> @@ -384,8 +384,8 @@ static void __init early_reserve_initrd(void)
> static void __init reserve_initrd(void)
> {
> /* Assume only end is not page aligned */
> - u64 ramdisk_image = get_ramdisk_image();
> - u64 ramdisk_size = get_ramdisk_size();
> + u64 ramdisk_image = get_ramdisk_image(&boot_params);
> + u64 ramdisk_size = get_ramdisk_size(&boot_params);
> u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
> u64 mapped_size;
>
> --
> 1.8.4.5
>
--
Kees Cook
Chrome OS Security
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/