diff options
author | Nicolas Pitre <nicolas.pitre@linaro.org> | 2011-02-21 00:57:33 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-02-23 11:14:25 -0500 |
commit | 3572bea8cbc57f0bef1e0f4580c01717df7026d8 (patch) | |
tree | aa48782419dad9dbd005783ff7af349e980b1de4 /arch/arm/kernel/setup.c | |
parent | dce72dd08c976c9e5e1367bf994b306b15ae87fe (diff) |
ARM: 6748/1: ignore mdesc->boot_params if out of range
The initial MMU table created in head.S contains a 1 MB mapping at the
start of memory to let the early kernel boot code access the boot params
specified by mdesc->boot_params.
When using CONFIG_ARM_PATCH_PHYS_VIRT it is possible for the kernel to
have a different idea of where the start of memory is at run time, making
the compile-time determined mdesc->boot_params pointing to a memory area
which is not mapped. Any access to the boot params in that case will
fault and silently hang the kernel at that point. It is therefore a
better idea to simply ignore mdesc->boot_params in that case and give
the kernel a chance to print some diagnostic on the console later.
If the bootloader provides a valid pointer in r2 to the kernel then this
is used instead of mdesc->boot_params, and an explicit mapping is already
created in the initial MMU table for it. It is therefore a good idea to
use that facility when using a relocated kernel.
Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/setup.c')
-rw-r--r-- | arch/arm/kernel/setup.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 6ce80106316e..f43f041a0977 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -839,8 +839,25 @@ void __init setup_arch(char **cmdline_p) | |||
839 | 839 | ||
840 | if (__atags_pointer) | 840 | if (__atags_pointer) |
841 | tags = phys_to_virt(__atags_pointer); | 841 | tags = phys_to_virt(__atags_pointer); |
842 | else if (mdesc->boot_params) | 842 | else if (mdesc->boot_params) { |
843 | tags = phys_to_virt(mdesc->boot_params); | 843 | #ifdef CONFIG_MMU |
844 | /* | ||
845 | * We still are executing with a minimal MMU mapping created | ||
846 | * with the presumption that the machine default for this | ||
847 | * is located in the first MB of RAM. Anything else will | ||
848 | * fault and silently hang the kernel at this point. | ||
849 | */ | ||
850 | if (mdesc->boot_params < PHYS_OFFSET || | ||
851 | mdesc->boot_params >= PHYS_OFFSET + SZ_1M) { | ||
852 | printk(KERN_WARNING | ||
853 | "Default boot params at physical 0x%08lx out of reach\n", | ||
854 | mdesc->boot_params); | ||
855 | } else | ||
856 | #endif | ||
857 | { | ||
858 | tags = phys_to_virt(mdesc->boot_params); | ||
859 | } | ||
860 | } | ||
844 | 861 | ||
845 | #if defined(CONFIG_DEPRECATED_PARAM_STRUCT) | 862 | #if defined(CONFIG_DEPRECATED_PARAM_STRUCT) |
846 | /* | 863 | /* |