Skip to content

Commit f6ff041

Browse files
Tyrel Datwylermpe
authored andcommitted
powerpc/pseries: Little endian fixes for post mobility device tree update
We currently use the device tree update code in the kernel after resuming from a suspend operation to re-sync the kernels view of the device tree with that of the hypervisor. The code as it stands is not endian safe as it relies on parsing buffers returned by RTAS calls that thusly contains data in big endian format. This patch annotates variables and structure members with __be types as well as performing necessary byte swaps to cpu endian for data that needs to be parsed. Signed-off-by: Tyrel Datwyler <[email protected]> Cc: Nathan Fontenot <[email protected]> Cc: Cyril Bur <[email protected]> Cc: [email protected] Signed-off-by: Michael Ellerman <[email protected]>
1 parent ddee09c commit f6ff041

File tree

1 file changed

+23
-21
lines changed

1 file changed

+23
-21
lines changed

arch/powerpc/platforms/pseries/mobility.c

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
static struct kobject *mobility_kobj;
2626

2727
struct update_props_workarea {
28-
u32 phandle;
29-
u32 state;
30-
u64 reserved;
31-
u32 nprops;
28+
__be32 phandle;
29+
__be32 state;
30+
__be64 reserved;
31+
__be32 nprops;
3232
} __packed;
3333

3434
#define NODE_ACTION_MASK 0xff000000
@@ -54,11 +54,11 @@ static int mobility_rtas_call(int token, char *buf, s32 scope)
5454
return rc;
5555
}
5656

57-
static int delete_dt_node(u32 phandle)
57+
static int delete_dt_node(__be32 phandle)
5858
{
5959
struct device_node *dn;
6060

61-
dn = of_find_node_by_phandle(phandle);
61+
dn = of_find_node_by_phandle(be32_to_cpu(phandle));
6262
if (!dn)
6363
return -ENOENT;
6464

@@ -127,7 +127,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
127127
return 0;
128128
}
129129

130-
static int update_dt_node(u32 phandle, s32 scope)
130+
static int update_dt_node(__be32 phandle, s32 scope)
131131
{
132132
struct update_props_workarea *upwa;
133133
struct device_node *dn;
@@ -136,6 +136,7 @@ static int update_dt_node(u32 phandle, s32 scope)
136136
char *prop_data;
137137
char *rtas_buf;
138138
int update_properties_token;
139+
u32 nprops;
139140
u32 vd;
140141

141142
update_properties_token = rtas_token("ibm,update-properties");
@@ -146,7 +147,7 @@ static int update_dt_node(u32 phandle, s32 scope)
146147
if (!rtas_buf)
147148
return -ENOMEM;
148149

149-
dn = of_find_node_by_phandle(phandle);
150+
dn = of_find_node_by_phandle(be32_to_cpu(phandle));
150151
if (!dn) {
151152
kfree(rtas_buf);
152153
return -ENOENT;
@@ -162,6 +163,7 @@ static int update_dt_node(u32 phandle, s32 scope)
162163
break;
163164

164165
prop_data = rtas_buf + sizeof(*upwa);
166+
nprops = be32_to_cpu(upwa->nprops);
165167

166168
/* On the first call to ibm,update-properties for a node the
167169
* the first property value descriptor contains an empty
@@ -170,17 +172,17 @@ static int update_dt_node(u32 phandle, s32 scope)
170172
*/
171173
if (*prop_data == 0) {
172174
prop_data++;
173-
vd = *(u32 *)prop_data;
175+
vd = be32_to_cpu(*(__be32 *)prop_data);
174176
prop_data += vd + sizeof(vd);
175-
upwa->nprops--;
177+
nprops--;
176178
}
177179

178-
for (i = 0; i < upwa->nprops; i++) {
180+
for (i = 0; i < nprops; i++) {
179181
char *prop_name;
180182

181183
prop_name = prop_data;
182184
prop_data += strlen(prop_name) + 1;
183-
vd = *(u32 *)prop_data;
185+
vd = be32_to_cpu(*(__be32 *)prop_data);
184186
prop_data += sizeof(vd);
185187

186188
switch (vd) {
@@ -212,13 +214,13 @@ static int update_dt_node(u32 phandle, s32 scope)
212214
return 0;
213215
}
214216

215-
static int add_dt_node(u32 parent_phandle, u32 drc_index)
217+
static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
216218
{
217219
struct device_node *dn;
218220
struct device_node *parent_dn;
219221
int rc;
220222

221-
parent_dn = of_find_node_by_phandle(parent_phandle);
223+
parent_dn = of_find_node_by_phandle(be32_to_cpu(parent_phandle));
222224
if (!parent_dn)
223225
return -ENOENT;
224226

@@ -237,7 +239,7 @@ static int add_dt_node(u32 parent_phandle, u32 drc_index)
237239
int pseries_devicetree_update(s32 scope)
238240
{
239241
char *rtas_buf;
240-
u32 *data;
242+
__be32 *data;
241243
int update_nodes_token;
242244
int rc;
243245

@@ -254,17 +256,17 @@ int pseries_devicetree_update(s32 scope)
254256
if (rc && rc != 1)
255257
break;
256258

257-
data = (u32 *)rtas_buf + 4;
258-
while (*data & NODE_ACTION_MASK) {
259+
data = (__be32 *)rtas_buf + 4;
260+
while (be32_to_cpu(*data) & NODE_ACTION_MASK) {
259261
int i;
260-
u32 action = *data & NODE_ACTION_MASK;
261-
int node_count = *data & NODE_COUNT_MASK;
262+
u32 action = be32_to_cpu(*data) & NODE_ACTION_MASK;
263+
u32 node_count = be32_to_cpu(*data) & NODE_COUNT_MASK;
262264

263265
data++;
264266

265267
for (i = 0; i < node_count; i++) {
266-
u32 phandle = *data++;
267-
u32 drc_index;
268+
__be32 phandle = *data++;
269+
__be32 drc_index;
268270

269271
switch (action) {
270272
case DELETE_DT_NODE:

0 commit comments

Comments
 (0)