From 97ec31f71c9d1d79efd9d65a90b7b14fea3c4416 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 6 May 2010 15:09:45 +0900 Subject: [PATCH] --- yaml --- r: 191649 b: refs/heads/master c: 9b7a37853a8cd69829eb1d9715a6c09aae01eeec h: refs/heads/master i: 191647: ef8c12a89b097641dc4c3624dad314c6d1003fb3 v: v3 --- [refs] | 2 +- trunk/arch/sh/kernel/setup.c | 78 +++++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/[refs] b/[refs] index 41d34bbda3d8..33339a4b46bf 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1483feac74fdfd84a7ed7586c66482842e3b6e86 +refs/heads/master: 9b7a37853a8cd69829eb1d9715a6c09aae01eeec diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index 14735d5ede52..9c7f7811af70 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -188,6 +188,63 @@ static inline void __init reserve_crashkernel(void) {} #endif +static void __init check_for_initrd(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD + unsigned long start, end; + + /* + * Check for the rare cases where boot loaders adhere to the boot + * ABI. + */ + if (!LOADER_TYPE || !INITRD_START || !INITRD_SIZE) + goto disable; + + start = INITRD_START + __MEMORY_START; + end = start + INITRD_SIZE; + + if (unlikely(end <= start)) + goto disable; + if (unlikely(start & ~PAGE_MASK)) { + pr_err("initrd must be page aligned\n"); + goto disable; + } + + if (unlikely(start < PAGE_OFFSET)) { + pr_err("initrd start < PAGE_OFFSET\n"); + goto disable; + } + + if (unlikely(end > lmb_end_of_DRAM())) { + pr_err("initrd extends beyond end of memory " + "(0x%08lx > 0x%08lx)\ndisabling initrd\n", + end, (unsigned long)lmb_end_of_DRAM()); + goto disable; + } + + /* + * If we got this far inspite of the boot loader's best efforts + * to the contrary, assume we actually have a valid initrd and + * fix up the root dev. + */ + ROOT_DEV = Root_RAM0; + + /* + * Address sanitization + */ + initrd_start = (unsigned long)__va(__pa(start)); + initrd_end = initrd_start + INITRD_SIZE; + + reserve_bootmem(__pa(initrd_start), INITRD_SIZE, BOOTMEM_DEFAULT); + + return; + +disable: + pr_info("initrd disabled\n"); + initrd_start = initrd_end = 0; +#endif +} + void __cpuinit calibrate_delay(void) { struct clk *clk = clk_get(NULL, "cpu_clk"); @@ -277,26 +334,7 @@ void __init setup_bootmem_allocator(unsigned long free_pfn) sparse_memory_present_with_active_regions(0); -#ifdef CONFIG_BLK_DEV_INITRD - ROOT_DEV = Root_RAM0; - - if (LOADER_TYPE && INITRD_START) { - unsigned long initrd_start_phys = INITRD_START + __MEMORY_START; - - if (initrd_start_phys + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) { - reserve_bootmem(initrd_start_phys, INITRD_SIZE, - BOOTMEM_DEFAULT); - initrd_start = (unsigned long)__va(initrd_start_phys); - initrd_end = initrd_start + INITRD_SIZE; - } else { - printk("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - initrd_start_phys + INITRD_SIZE, - (unsigned long)PFN_PHYS(max_low_pfn)); - initrd_start = 0; - } - } -#endif + check_for_initrd(); reserve_crashkernel(); }