diff options
| author | Vineet Gupta <vgupta@synopsys.com> | 2013-02-21 07:07:06 -0500 |
|---|---|---|
| committer | Vineet Gupta <vgupta@synopsys.com> | 2013-02-26 03:55:18 -0500 |
| commit | eab6a08c082b82dff884eb49a2229b0474d0b7e5 (patch) | |
| tree | 4acffa75b89ecdef8d4f38558155b0afdd2fbe19 | |
| parent | fc32781bfdb56dad883469b65e468e749ef35fe5 (diff) | |
ARC: make a copy of flat DT
The flat DT (currently embedded in vmlinux) is in .init section.
The unflattened/binary tree doesn't copy strings through and references
them from orig flat DT - which could cause catestrohpy if of_* APIs are
called post init, say from a driver which is a loadable module.
Reported-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
| -rw-r--r-- | arch/arc/include/asm/mach_desc.h | 2 | ||||
| -rw-r--r-- | arch/arc/kernel/devtree.c | 15 | ||||
| -rw-r--r-- | arch/arc/kernel/setup.c | 2 |
3 files changed, 19 insertions, 0 deletions
diff --git a/arch/arc/include/asm/mach_desc.h b/arch/arc/include/asm/mach_desc.h index eaebaf835f85..9998dc846ebb 100644 --- a/arch/arc/include/asm/mach_desc.h +++ b/arch/arc/include/asm/mach_desc.h | |||
| @@ -82,4 +82,6 @@ __attribute__((__section__(".arch.info.init"))) = { \ | |||
| 82 | }; | 82 | }; |
| 83 | 83 | ||
| 84 | extern struct machine_desc *setup_machine_fdt(void *dt); | 84 | extern struct machine_desc *setup_machine_fdt(void *dt); |
| 85 | extern void __init copy_devtree(void); | ||
| 86 | |||
| 85 | #endif | 87 | #endif |
diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c index a7d98b30358b..bdee3a812052 100644 --- a/arch/arc/kernel/devtree.c +++ b/arch/arc/kernel/devtree.c | |||
| @@ -106,3 +106,18 @@ struct machine_desc * __init setup_machine_fdt(void *dt) | |||
| 106 | 106 | ||
| 107 | return mdesc_best; | 107 | return mdesc_best; |
| 108 | } | 108 | } |
| 109 | |||
| 110 | /* | ||
| 111 | * Copy the flattened DT out of .init since unflattening doesn't copy strings | ||
| 112 | * and the normal DT APIs refs them from orig flat DT | ||
| 113 | */ | ||
| 114 | void __init copy_devtree(void) | ||
| 115 | { | ||
| 116 | void *alloc = early_init_dt_alloc_memory_arch( | ||
| 117 | be32_to_cpu(initial_boot_params->totalsize), 64); | ||
| 118 | if (alloc) { | ||
| 119 | memcpy(alloc, initial_boot_params, | ||
| 120 | be32_to_cpu(initial_boot_params->totalsize)); | ||
| 121 | initial_boot_params = alloc; | ||
| 122 | } | ||
| 123 | } | ||
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index e591c6ae88a6..dc0f968dae0a 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c | |||
| @@ -354,6 +354,8 @@ void __init setup_arch(char **cmdline_p) | |||
| 354 | 354 | ||
| 355 | setup_arch_memory(); | 355 | setup_arch_memory(); |
| 356 | 356 | ||
| 357 | /* copy flat DT out of .init and then unflatten it */ | ||
| 358 | copy_devtree(); | ||
| 357 | unflatten_device_tree(); | 359 | unflatten_device_tree(); |
| 358 | 360 | ||
| 359 | /* Can be issue if someone passes cmd line arg "ro" | 361 | /* Can be issue if someone passes cmd line arg "ro" |
