diff options
author | Thomas Falcon <tlfalcon@linux.vnet.ibm.com> | 2014-09-12 15:11:42 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2014-09-25 09:14:48 -0400 |
commit | e36d1227776a2daa2c9aa7f997ac7083d6783f2c (patch) | |
tree | cf21c3d622ddf8674c1f352db8fceddba09aa730 /arch | |
parent | 822e71224e07f07a07c385be869fe416ce436430 (diff) |
pseries: Fix endian issues in cpu hot-removal
When removing a cpu, this patch makes sure that values
gotten from or passed to firmware are in the correct
endian format.
Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pseries/dlpar.c | 20 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/hotplug-cpu.c | 10 |
2 files changed, 17 insertions, 13 deletions
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 096337853dda..fdf01b660d59 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
@@ -445,7 +445,8 @@ static int dlpar_offline_cpu(struct device_node *dn) | |||
445 | int rc = 0; | 445 | int rc = 0; |
446 | unsigned int cpu; | 446 | unsigned int cpu; |
447 | int len, nthreads, i; | 447 | int len, nthreads, i; |
448 | const u32 *intserv; | 448 | const __be32 *intserv; |
449 | u32 thread; | ||
449 | 450 | ||
450 | intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len); | 451 | intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len); |
451 | if (!intserv) | 452 | if (!intserv) |
@@ -455,8 +456,9 @@ static int dlpar_offline_cpu(struct device_node *dn) | |||
455 | 456 | ||
456 | cpu_maps_update_begin(); | 457 | cpu_maps_update_begin(); |
457 | for (i = 0; i < nthreads; i++) { | 458 | for (i = 0; i < nthreads; i++) { |
459 | thread = be32_to_cpu(intserv[i]); | ||
458 | for_each_present_cpu(cpu) { | 460 | for_each_present_cpu(cpu) { |
459 | if (get_hard_smp_processor_id(cpu) != intserv[i]) | 461 | if (get_hard_smp_processor_id(cpu) != thread) |
460 | continue; | 462 | continue; |
461 | 463 | ||
462 | if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE) | 464 | if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE) |
@@ -478,14 +480,14 @@ static int dlpar_offline_cpu(struct device_node *dn) | |||
478 | * Upgrade it's state to CPU_STATE_OFFLINE. | 480 | * Upgrade it's state to CPU_STATE_OFFLINE. |
479 | */ | 481 | */ |
480 | set_preferred_offline_state(cpu, CPU_STATE_OFFLINE); | 482 | set_preferred_offline_state(cpu, CPU_STATE_OFFLINE); |
481 | BUG_ON(plpar_hcall_norets(H_PROD, intserv[i]) | 483 | BUG_ON(plpar_hcall_norets(H_PROD, thread) |
482 | != H_SUCCESS); | 484 | != H_SUCCESS); |
483 | __cpu_die(cpu); | 485 | __cpu_die(cpu); |
484 | break; | 486 | break; |
485 | } | 487 | } |
486 | if (cpu == num_possible_cpus()) | 488 | if (cpu == num_possible_cpus()) |
487 | printk(KERN_WARNING "Could not find cpu to offline " | 489 | printk(KERN_WARNING "Could not find cpu to offline " |
488 | "with physical id 0x%x\n", intserv[i]); | 490 | "with physical id 0x%x\n", thread); |
489 | } | 491 | } |
490 | cpu_maps_update_done(); | 492 | cpu_maps_update_done(); |
491 | 493 | ||
@@ -497,15 +499,15 @@ out: | |||
497 | static ssize_t dlpar_cpu_release(const char *buf, size_t count) | 499 | static ssize_t dlpar_cpu_release(const char *buf, size_t count) |
498 | { | 500 | { |
499 | struct device_node *dn; | 501 | struct device_node *dn; |
500 | const u32 *drc_index; | 502 | u32 drc_index; |
501 | int rc; | 503 | int rc; |
502 | 504 | ||
503 | dn = of_find_node_by_path(buf); | 505 | dn = of_find_node_by_path(buf); |
504 | if (!dn) | 506 | if (!dn) |
505 | return -EINVAL; | 507 | return -EINVAL; |
506 | 508 | ||
507 | drc_index = of_get_property(dn, "ibm,my-drc-index", NULL); | 509 | rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index); |
508 | if (!drc_index) { | 510 | if (rc) { |
509 | of_node_put(dn); | 511 | of_node_put(dn); |
510 | return -EINVAL; | 512 | return -EINVAL; |
511 | } | 513 | } |
@@ -516,7 +518,7 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count) | |||
516 | return -EINVAL; | 518 | return -EINVAL; |
517 | } | 519 | } |
518 | 520 | ||
519 | rc = dlpar_release_drc(*drc_index); | 521 | rc = dlpar_release_drc(drc_index); |
520 | if (rc) { | 522 | if (rc) { |
521 | of_node_put(dn); | 523 | of_node_put(dn); |
522 | return rc; | 524 | return rc; |
@@ -524,7 +526,7 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count) | |||
524 | 526 | ||
525 | rc = dlpar_detach_node(dn); | 527 | rc = dlpar_detach_node(dn); |
526 | if (rc) { | 528 | if (rc) { |
527 | dlpar_acquire_drc(*drc_index); | 529 | dlpar_acquire_drc(drc_index); |
528 | return rc; | 530 | return rc; |
529 | } | 531 | } |
530 | 532 | ||
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 20d62975856f..b174fa751d26 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c | |||
@@ -90,7 +90,7 @@ static void rtas_stop_self(void) | |||
90 | { | 90 | { |
91 | static struct rtas_args args = { | 91 | static struct rtas_args args = { |
92 | .nargs = 0, | 92 | .nargs = 0, |
93 | .nret = 1, | 93 | .nret = cpu_to_be32(1), |
94 | .rets = &args.args[0], | 94 | .rets = &args.args[0], |
95 | }; | 95 | }; |
96 | 96 | ||
@@ -312,7 +312,8 @@ static void pseries_remove_processor(struct device_node *np) | |||
312 | { | 312 | { |
313 | unsigned int cpu; | 313 | unsigned int cpu; |
314 | int len, nthreads, i; | 314 | int len, nthreads, i; |
315 | const u32 *intserv; | 315 | const __be32 *intserv; |
316 | u32 thread; | ||
316 | 317 | ||
317 | intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len); | 318 | intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len); |
318 | if (!intserv) | 319 | if (!intserv) |
@@ -322,8 +323,9 @@ static void pseries_remove_processor(struct device_node *np) | |||
322 | 323 | ||
323 | cpu_maps_update_begin(); | 324 | cpu_maps_update_begin(); |
324 | for (i = 0; i < nthreads; i++) { | 325 | for (i = 0; i < nthreads; i++) { |
326 | thread = be32_to_cpu(intserv[i]); | ||
325 | for_each_present_cpu(cpu) { | 327 | for_each_present_cpu(cpu) { |
326 | if (get_hard_smp_processor_id(cpu) != intserv[i]) | 328 | if (get_hard_smp_processor_id(cpu) != thread) |
327 | continue; | 329 | continue; |
328 | BUG_ON(cpu_online(cpu)); | 330 | BUG_ON(cpu_online(cpu)); |
329 | set_cpu_present(cpu, false); | 331 | set_cpu_present(cpu, false); |
@@ -332,7 +334,7 @@ static void pseries_remove_processor(struct device_node *np) | |||
332 | } | 334 | } |
333 | if (cpu >= nr_cpu_ids) | 335 | if (cpu >= nr_cpu_ids) |
334 | printk(KERN_WARNING "Could not find cpu to remove " | 336 | printk(KERN_WARNING "Could not find cpu to remove " |
335 | "with physical id 0x%x\n", intserv[i]); | 337 | "with physical id 0x%x\n", thread); |
336 | } | 338 | } |
337 | cpu_maps_update_done(); | 339 | cpu_maps_update_done(); |
338 | } | 340 | } |