diff options
author | Bharata B Rao <bharata@linux.vnet.ibm.com> | 2014-09-16 16:15:45 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2014-10-14 20:25:59 -0400 |
commit | d6f1e7abdb95a7ea031e7604829e4b5514d7e2c1 (patch) | |
tree | db670fc5c988288ce66ccea21343105a7c35c361 | |
parent | 4ff52b4dedcd4226cf1f2817eb14e8d733790eae (diff) |
powerpc/pseries: Make CPU hotplug path endian safe
- ibm,rtas-configure-connector should treat the RTAS data as big endian.
- Treat ibm,ppc-interrupt-server#s as big-endian when setting
smp_processor_id during hotplug.
Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | arch/powerpc/platforms/pseries/dlpar.c | 22 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/hotplug-cpu.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/pseries.h | 3 |
3 files changed, 15 insertions, 14 deletions
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index fdf01b660d59..6ad83bd11fe2 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
@@ -25,11 +25,11 @@ | |||
25 | #include <asm/rtas.h> | 25 | #include <asm/rtas.h> |
26 | 26 | ||
27 | struct cc_workarea { | 27 | struct cc_workarea { |
28 | u32 drc_index; | 28 | __be32 drc_index; |
29 | u32 zero; | 29 | __be32 zero; |
30 | u32 name_offset; | 30 | __be32 name_offset; |
31 | u32 prop_length; | 31 | __be32 prop_length; |
32 | u32 prop_offset; | 32 | __be32 prop_offset; |
33 | }; | 33 | }; |
34 | 34 | ||
35 | void dlpar_free_cc_property(struct property *prop) | 35 | void dlpar_free_cc_property(struct property *prop) |
@@ -49,11 +49,11 @@ static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa) | |||
49 | if (!prop) | 49 | if (!prop) |
50 | return NULL; | 50 | return NULL; |
51 | 51 | ||
52 | name = (char *)ccwa + ccwa->name_offset; | 52 | name = (char *)ccwa + be32_to_cpu(ccwa->name_offset); |
53 | prop->name = kstrdup(name, GFP_KERNEL); | 53 | prop->name = kstrdup(name, GFP_KERNEL); |
54 | 54 | ||
55 | prop->length = ccwa->prop_length; | 55 | prop->length = be32_to_cpu(ccwa->prop_length); |
56 | value = (char *)ccwa + ccwa->prop_offset; | 56 | value = (char *)ccwa + be32_to_cpu(ccwa->prop_offset); |
57 | prop->value = kmemdup(value, prop->length, GFP_KERNEL); | 57 | prop->value = kmemdup(value, prop->length, GFP_KERNEL); |
58 | if (!prop->value) { | 58 | if (!prop->value) { |
59 | dlpar_free_cc_property(prop); | 59 | dlpar_free_cc_property(prop); |
@@ -79,7 +79,7 @@ static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa, | |||
79 | if (!dn) | 79 | if (!dn) |
80 | return NULL; | 80 | return NULL; |
81 | 81 | ||
82 | name = (char *)ccwa + ccwa->name_offset; | 82 | name = (char *)ccwa + be32_to_cpu(ccwa->name_offset); |
83 | dn->full_name = kasprintf(GFP_KERNEL, "%s/%s", path, name); | 83 | dn->full_name = kasprintf(GFP_KERNEL, "%s/%s", path, name); |
84 | if (!dn->full_name) { | 84 | if (!dn->full_name) { |
85 | kfree(dn); | 85 | kfree(dn); |
@@ -126,7 +126,7 @@ void dlpar_free_cc_nodes(struct device_node *dn) | |||
126 | #define CALL_AGAIN -2 | 126 | #define CALL_AGAIN -2 |
127 | #define ERR_CFG_USE -9003 | 127 | #define ERR_CFG_USE -9003 |
128 | 128 | ||
129 | struct device_node *dlpar_configure_connector(u32 drc_index, | 129 | struct device_node *dlpar_configure_connector(__be32 drc_index, |
130 | struct device_node *parent) | 130 | struct device_node *parent) |
131 | { | 131 | { |
132 | struct device_node *dn; | 132 | struct device_node *dn; |
@@ -414,7 +414,7 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) | |||
414 | if (!parent) | 414 | if (!parent) |
415 | return -ENODEV; | 415 | return -ENODEV; |
416 | 416 | ||
417 | dn = dlpar_configure_connector(drc_index, parent); | 417 | dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent); |
418 | if (!dn) | 418 | if (!dn) |
419 | return -EINVAL; | 419 | return -EINVAL; |
420 | 420 | ||
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index b174fa751d26..5c375f93c669 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c | |||
@@ -247,7 +247,7 @@ static int pseries_add_processor(struct device_node *np) | |||
247 | unsigned int cpu; | 247 | unsigned int cpu; |
248 | cpumask_var_t candidate_mask, tmp; | 248 | cpumask_var_t candidate_mask, tmp; |
249 | int err = -ENOSPC, len, nthreads, i; | 249 | int err = -ENOSPC, len, nthreads, i; |
250 | const u32 *intserv; | 250 | const __be32 *intserv; |
251 | 251 | ||
252 | intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len); | 252 | intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len); |
253 | if (!intserv) | 253 | if (!intserv) |
@@ -293,7 +293,7 @@ static int pseries_add_processor(struct device_node *np) | |||
293 | for_each_cpu(cpu, tmp) { | 293 | for_each_cpu(cpu, tmp) { |
294 | BUG_ON(cpu_present(cpu)); | 294 | BUG_ON(cpu_present(cpu)); |
295 | set_cpu_present(cpu, true); | 295 | set_cpu_present(cpu, true); |
296 | set_hard_smp_processor_id(cpu, *intserv++); | 296 | set_hard_smp_processor_id(cpu, be32_to_cpu(*intserv++)); |
297 | } | 297 | } |
298 | err = 0; | 298 | err = 0; |
299 | out_unlock: | 299 | out_unlock: |
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 361add62abf1..1796c5438cc6 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h | |||
@@ -56,7 +56,8 @@ extern void hvc_vio_init_early(void); | |||
56 | /* Dynamic logical Partitioning/Mobility */ | 56 | /* Dynamic logical Partitioning/Mobility */ |
57 | extern void dlpar_free_cc_nodes(struct device_node *); | 57 | extern void dlpar_free_cc_nodes(struct device_node *); |
58 | extern void dlpar_free_cc_property(struct property *); | 58 | extern void dlpar_free_cc_property(struct property *); |
59 | extern struct device_node *dlpar_configure_connector(u32, struct device_node *); | 59 | extern struct device_node *dlpar_configure_connector(__be32, |
60 | struct device_node *); | ||
60 | extern int dlpar_attach_node(struct device_node *); | 61 | extern int dlpar_attach_node(struct device_node *); |
61 | extern int dlpar_detach_node(struct device_node *); | 62 | extern int dlpar_detach_node(struct device_node *); |
62 | 63 | ||