diff options
author | Ian Munsie <imunsie@au1.ibm.com> | 2013-08-06 12:01:27 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-08-14 01:33:19 -0400 |
commit | dc0e643afc505e7feeac5f86e8fe82183847ebe7 (patch) | |
tree | 25c2953fdec1d2fe3294eddad0d66077849eb3f1 /arch/powerpc/kernel/prom.c | |
parent | bc2e6c6ac21183a6102a926f83186d9cac6713f8 (diff) |
powerpc: Make prom.c device tree accesses endian safe
On PowerPC the device tree is always big endian, but the CPU could be
either, so add be32_to_cpu where appropriate and change the types of
device tree data to __be32 etc to allow sparse to locate endian issues.
Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r-- | arch/powerpc/kernel/prom.c | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 2de07e52c356..d8a687c5e3ee 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -215,16 +215,16 @@ static void __init check_cpu_pa_features(unsigned long node) | |||
215 | #ifdef CONFIG_PPC_STD_MMU_64 | 215 | #ifdef CONFIG_PPC_STD_MMU_64 |
216 | static void __init check_cpu_slb_size(unsigned long node) | 216 | static void __init check_cpu_slb_size(unsigned long node) |
217 | { | 217 | { |
218 | u32 *slb_size_ptr; | 218 | __be32 *slb_size_ptr; |
219 | 219 | ||
220 | slb_size_ptr = of_get_flat_dt_prop(node, "slb-size", NULL); | 220 | slb_size_ptr = of_get_flat_dt_prop(node, "slb-size", NULL); |
221 | if (slb_size_ptr != NULL) { | 221 | if (slb_size_ptr != NULL) { |
222 | mmu_slb_size = *slb_size_ptr; | 222 | mmu_slb_size = be32_to_cpup(slb_size_ptr); |
223 | return; | 223 | return; |
224 | } | 224 | } |
225 | slb_size_ptr = of_get_flat_dt_prop(node, "ibm,slb-size", NULL); | 225 | slb_size_ptr = of_get_flat_dt_prop(node, "ibm,slb-size", NULL); |
226 | if (slb_size_ptr != NULL) { | 226 | if (slb_size_ptr != NULL) { |
227 | mmu_slb_size = *slb_size_ptr; | 227 | mmu_slb_size = be32_to_cpup(slb_size_ptr); |
228 | } | 228 | } |
229 | } | 229 | } |
230 | #else | 230 | #else |
@@ -279,11 +279,11 @@ static void __init check_cpu_feature_properties(unsigned long node) | |||
279 | { | 279 | { |
280 | unsigned long i; | 280 | unsigned long i; |
281 | struct feature_property *fp = feature_properties; | 281 | struct feature_property *fp = feature_properties; |
282 | const u32 *prop; | 282 | const __be32 *prop; |
283 | 283 | ||
284 | for (i = 0; i < ARRAY_SIZE(feature_properties); ++i, ++fp) { | 284 | for (i = 0; i < ARRAY_SIZE(feature_properties); ++i, ++fp) { |
285 | prop = of_get_flat_dt_prop(node, fp->name, NULL); | 285 | prop = of_get_flat_dt_prop(node, fp->name, NULL); |
286 | if (prop && *prop >= fp->min_value) { | 286 | if (prop && be32_to_cpup(prop) >= fp->min_value) { |
287 | cur_cpu_spec->cpu_features |= fp->cpu_feature; | 287 | cur_cpu_spec->cpu_features |= fp->cpu_feature; |
288 | cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftr; | 288 | cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftr; |
289 | } | 289 | } |
@@ -295,8 +295,8 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
295 | void *data) | 295 | void *data) |
296 | { | 296 | { |
297 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | 297 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); |
298 | const u32 *prop; | 298 | const __be32 *prop; |
299 | const u32 *intserv; | 299 | const __be32 *intserv; |
300 | int i, nthreads; | 300 | int i, nthreads; |
301 | unsigned long len; | 301 | unsigned long len; |
302 | int found = -1; | 302 | int found = -1; |
@@ -324,8 +324,9 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
324 | * version 2 of the kexec param format adds the phys cpuid of | 324 | * version 2 of the kexec param format adds the phys cpuid of |
325 | * booted proc. | 325 | * booted proc. |
326 | */ | 326 | */ |
327 | if (initial_boot_params->version >= 2) { | 327 | if (be32_to_cpu(initial_boot_params->version) >= 2) { |
328 | if (intserv[i] == initial_boot_params->boot_cpuid_phys) { | 328 | if (be32_to_cpu(intserv[i]) == |
329 | be32_to_cpu(initial_boot_params->boot_cpuid_phys)) { | ||
329 | found = boot_cpu_count; | 330 | found = boot_cpu_count; |
330 | found_thread = i; | 331 | found_thread = i; |
331 | } | 332 | } |
@@ -347,9 +348,10 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
347 | 348 | ||
348 | if (found >= 0) { | 349 | if (found >= 0) { |
349 | DBG("boot cpu: logical %d physical %d\n", found, | 350 | DBG("boot cpu: logical %d physical %d\n", found, |
350 | intserv[found_thread]); | 351 | be32_to_cpu(intserv[found_thread])); |
351 | boot_cpuid = found; | 352 | boot_cpuid = found; |
352 | set_hard_smp_processor_id(found, intserv[found_thread]); | 353 | set_hard_smp_processor_id(found, |
354 | be32_to_cpu(intserv[found_thread])); | ||
353 | 355 | ||
354 | /* | 356 | /* |
355 | * PAPR defines "logical" PVR values for cpus that | 357 | * PAPR defines "logical" PVR values for cpus that |
@@ -366,8 +368,8 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
366 | * it uses 0x0f000001. | 368 | * it uses 0x0f000001. |
367 | */ | 369 | */ |
368 | prop = of_get_flat_dt_prop(node, "cpu-version", NULL); | 370 | prop = of_get_flat_dt_prop(node, "cpu-version", NULL); |
369 | if (prop && (*prop & 0xff000000) == 0x0f000000) | 371 | if (prop && (be32_to_cpup(prop) & 0xff000000) == 0x0f000000) |
370 | identify_cpu(0, *prop); | 372 | identify_cpu(0, be32_to_cpup(prop)); |
371 | 373 | ||
372 | identical_pvr_fixup(node); | 374 | identical_pvr_fixup(node); |
373 | } | 375 | } |
@@ -389,7 +391,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
389 | int __init early_init_dt_scan_chosen_ppc(unsigned long node, const char *uname, | 391 | int __init early_init_dt_scan_chosen_ppc(unsigned long node, const char *uname, |
390 | int depth, void *data) | 392 | int depth, void *data) |
391 | { | 393 | { |
392 | unsigned long *lprop; | 394 | unsigned long *lprop; /* All these set by kernel, so no need to convert endian */ |
393 | 395 | ||
394 | /* Use common scan routine to determine if this is the chosen node */ | 396 | /* Use common scan routine to determine if this is the chosen node */ |
395 | if (early_init_dt_scan_chosen(node, uname, depth, data) == 0) | 397 | if (early_init_dt_scan_chosen(node, uname, depth, data) == 0) |
@@ -591,16 +593,16 @@ static void __init early_reserve_mem_dt(void) | |||
591 | static void __init early_reserve_mem(void) | 593 | static void __init early_reserve_mem(void) |
592 | { | 594 | { |
593 | u64 base, size; | 595 | u64 base, size; |
594 | u64 *reserve_map; | 596 | __be64 *reserve_map; |
595 | unsigned long self_base; | 597 | unsigned long self_base; |
596 | unsigned long self_size; | 598 | unsigned long self_size; |
597 | 599 | ||
598 | reserve_map = (u64 *)(((unsigned long)initial_boot_params) + | 600 | reserve_map = (__be64 *)(((unsigned long)initial_boot_params) + |
599 | initial_boot_params->off_mem_rsvmap); | 601 | be32_to_cpu(initial_boot_params->off_mem_rsvmap)); |
600 | 602 | ||
601 | /* before we do anything, lets reserve the dt blob */ | 603 | /* before we do anything, lets reserve the dt blob */ |
602 | self_base = __pa((unsigned long)initial_boot_params); | 604 | self_base = __pa((unsigned long)initial_boot_params); |
603 | self_size = initial_boot_params->totalsize; | 605 | self_size = be32_to_cpu(initial_boot_params->totalsize); |
604 | memblock_reserve(self_base, self_size); | 606 | memblock_reserve(self_base, self_size); |
605 | 607 | ||
606 | /* Look for the new "reserved-regions" property in the DT */ | 608 | /* Look for the new "reserved-regions" property in the DT */ |
@@ -620,15 +622,15 @@ static void __init early_reserve_mem(void) | |||
620 | * Handle the case where we might be booting from an old kexec | 622 | * Handle the case where we might be booting from an old kexec |
621 | * image that setup the mem_rsvmap as pairs of 32-bit values | 623 | * image that setup the mem_rsvmap as pairs of 32-bit values |
622 | */ | 624 | */ |
623 | if (*reserve_map > 0xffffffffull) { | 625 | if (be64_to_cpup(reserve_map) > 0xffffffffull) { |
624 | u32 base_32, size_32; | 626 | u32 base_32, size_32; |
625 | u32 *reserve_map_32 = (u32 *)reserve_map; | 627 | __be32 *reserve_map_32 = (__be32 *)reserve_map; |
626 | 628 | ||
627 | DBG("Found old 32-bit reserve map\n"); | 629 | DBG("Found old 32-bit reserve map\n"); |
628 | 630 | ||
629 | while (1) { | 631 | while (1) { |
630 | base_32 = *(reserve_map_32++); | 632 | base_32 = be32_to_cpup(reserve_map_32++); |
631 | size_32 = *(reserve_map_32++); | 633 | size_32 = be32_to_cpup(reserve_map_32++); |
632 | if (size_32 == 0) | 634 | if (size_32 == 0) |
633 | break; | 635 | break; |
634 | /* skip if the reservation is for the blob */ | 636 | /* skip if the reservation is for the blob */ |
@@ -644,8 +646,8 @@ static void __init early_reserve_mem(void) | |||
644 | 646 | ||
645 | /* Handle the reserve map in the fdt blob if it exists */ | 647 | /* Handle the reserve map in the fdt blob if it exists */ |
646 | while (1) { | 648 | while (1) { |
647 | base = *(reserve_map++); | 649 | base = be64_to_cpup(reserve_map++); |
648 | size = *(reserve_map++); | 650 | size = be64_to_cpup(reserve_map++); |
649 | if (size == 0) | 651 | if (size == 0) |
650 | break; | 652 | break; |
651 | DBG("reserving: %llx -> %llx\n", base, size); | 653 | DBG("reserving: %llx -> %llx\n", base, size); |
@@ -903,7 +905,7 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | |||
903 | hardid = get_hard_smp_processor_id(cpu); | 905 | hardid = get_hard_smp_processor_id(cpu); |
904 | 906 | ||
905 | for_each_node_by_type(np, "cpu") { | 907 | for_each_node_by_type(np, "cpu") { |
906 | const u32 *intserv; | 908 | const __be32 *intserv; |
907 | unsigned int plen, t; | 909 | unsigned int plen, t; |
908 | 910 | ||
909 | /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist | 911 | /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist |
@@ -912,10 +914,10 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | |||
912 | intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", | 914 | intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", |
913 | &plen); | 915 | &plen); |
914 | if (intserv == NULL) { | 916 | if (intserv == NULL) { |
915 | const u32 *reg = of_get_property(np, "reg", NULL); | 917 | const __be32 *reg = of_get_property(np, "reg", NULL); |
916 | if (reg == NULL) | 918 | if (reg == NULL) |
917 | continue; | 919 | continue; |
918 | if (*reg == hardid) { | 920 | if (be32_to_cpup(reg) == hardid) { |
919 | if (thread) | 921 | if (thread) |
920 | *thread = 0; | 922 | *thread = 0; |
921 | return np; | 923 | return np; |
@@ -923,7 +925,7 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | |||
923 | } else { | 925 | } else { |
924 | plen /= sizeof(u32); | 926 | plen /= sizeof(u32); |
925 | for (t = 0; t < plen; t++) { | 927 | for (t = 0; t < plen; t++) { |
926 | if (hardid == intserv[t]) { | 928 | if (hardid == be32_to_cpu(intserv[t])) { |
927 | if (thread) | 929 | if (thread) |
928 | *thread = t; | 930 | *thread = t; |
929 | return np; | 931 | return np; |
@@ -943,7 +945,7 @@ static int __init export_flat_device_tree(void) | |||
943 | struct dentry *d; | 945 | struct dentry *d; |
944 | 946 | ||
945 | flat_dt_blob.data = initial_boot_params; | 947 | flat_dt_blob.data = initial_boot_params; |
946 | flat_dt_blob.size = initial_boot_params->totalsize; | 948 | flat_dt_blob.size = be32_to_cpu(initial_boot_params->totalsize); |
947 | 949 | ||
948 | d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, | 950 | d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, |
949 | powerpc_debugfs_root, &flat_dt_blob); | 951 | powerpc_debugfs_root, &flat_dt_blob); |