diff options
author | James Hogan | 2013-02-20 13:59:13 +0000 |
---|---|---|
committer | James Hogan | 2013-03-02 20:11:17 +0000 |
commit | 2270e6d30bb6601ffd42e9d972442df0499ad547 (patch) | |
tree | c72e32a15d041cfe38560dca277f335da3f6e7cf | |
parent | d7900504480ea9d49a6b5f8811f2678ad08d3255 (diff) |
metag: copy devicetree to non-init memory
Make a copy of the device tree blob in non-init memory. It is required
when using built-in device tree files that the platform code copies the
blob to non-init memory prior to calling unflatten_device_tree(),
otherwise the strings that the device tree refer to will get poisoned
and potentially reused, breaking later reading of the device tree
post-init (such as compatible matching in modules, debugfs, and the
procfs interface).
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/metag/include/asm/prom.h | 1 | ||||
-rw-r--r-- | arch/metag/kernel/devtree.c | 17 | ||||
-rw-r--r-- | arch/metag/kernel/setup.c | 2 |
3 files changed, 20 insertions, 0 deletions
diff --git a/arch/metag/include/asm/prom.h b/arch/metag/include/asm/prom.h index d881396c392c..ccac97e865d0 100644 --- a/arch/metag/include/asm/prom.h +++ b/arch/metag/include/asm/prom.h @@ -18,6 +18,7 @@ #define HAVE_ARCH_DEVTREE_FIXUPS extern struct machine_desc *setup_machine_fdt(void *dt); +extern void copy_fdt(void); extern void metag_dt_memblock_reserve(void); #endif /* __ASM_METAG_PROM_H */ diff --git a/arch/metag/kernel/devtree.c b/arch/metag/kernel/devtree.c index 5b6b1d855492..7cd02529636e 100644 --- a/arch/metag/kernel/devtree.c +++ b/arch/metag/kernel/devtree.c @@ -95,3 +95,20 @@ struct machine_desc * __init setup_machine_fdt(void *dt) return mdesc_best; } + +/** + * copy_fdt - Copy device tree into non-init memory. + * + * We must copy the flattened device tree blob into non-init memory because the + * unflattened device tree will reference the strings in it directly. + */ +void __init copy_fdt(void) +{ + void *alloc = early_init_dt_alloc_memory_arch( + be32_to_cpu(initial_boot_params->totalsize), 0x40); + if (alloc) { + memcpy(alloc, initial_boot_params, + be32_to_cpu(initial_boot_params->totalsize)); + initial_boot_params = alloc; + } +} diff --git a/arch/metag/kernel/setup.c b/arch/metag/kernel/setup.c index dd6c5ad73917..879246170aec 100644 --- a/arch/metag/kernel/setup.c +++ b/arch/metag/kernel/setup.c @@ -406,6 +406,8 @@ void __init setup_arch(char **cmdline_p) cpu_2_hwthread_id[smp_processor_id()] = hard_processor_id(); hwthread_id_2_cpu[hard_processor_id()] = smp_processor_id(); + /* Copy device tree blob into non-init memory before unflattening */ + copy_fdt(); unflatten_device_tree(); #ifdef CONFIG_SMP |