Skip to content

Commit

Permalink
powerpc/pseries: Little endian fixes for post mobility device tree up…
Browse files Browse the repository at this point in the history
…date

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]>
  • Loading branch information
Tyrel Datwyler authored and mpe committed Mar 20, 2015
1 parent ddee09c commit f6ff041
Showing 1 changed file with 23 additions and 21 deletions.
44 changes: 23 additions & 21 deletions arch/powerpc/platforms/pseries/mobility.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
static struct kobject *mobility_kobj;

struct update_props_workarea {
u32 phandle;
u32 state;
u64 reserved;
u32 nprops;
__be32 phandle;
__be32 state;
__be64 reserved;
__be32 nprops;
} __packed;

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

static int delete_dt_node(u32 phandle)
static int delete_dt_node(__be32 phandle)
{
struct device_node *dn;

dn = of_find_node_by_phandle(phandle);
dn = of_find_node_by_phandle(be32_to_cpu(phandle));
if (!dn)
return -ENOENT;

Expand Down Expand Up @@ -127,7 +127,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
return 0;
}

static int update_dt_node(u32 phandle, s32 scope)
static int update_dt_node(__be32 phandle, s32 scope)
{
struct update_props_workarea *upwa;
struct device_node *dn;
Expand All @@ -136,6 +136,7 @@ static int update_dt_node(u32 phandle, s32 scope)
char *prop_data;
char *rtas_buf;
int update_properties_token;
u32 nprops;
u32 vd;

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

dn = of_find_node_by_phandle(phandle);
dn = of_find_node_by_phandle(be32_to_cpu(phandle));
if (!dn) {
kfree(rtas_buf);
return -ENOENT;
Expand All @@ -162,6 +163,7 @@ static int update_dt_node(u32 phandle, s32 scope)
break;

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

/* On the first call to ibm,update-properties for a node the
* the first property value descriptor contains an empty
Expand All @@ -170,17 +172,17 @@ static int update_dt_node(u32 phandle, s32 scope)
*/
if (*prop_data == 0) {
prop_data++;
vd = *(u32 *)prop_data;
vd = be32_to_cpu(*(__be32 *)prop_data);
prop_data += vd + sizeof(vd);
upwa->nprops--;
nprops--;
}

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

prop_name = prop_data;
prop_data += strlen(prop_name) + 1;
vd = *(u32 *)prop_data;
vd = be32_to_cpu(*(__be32 *)prop_data);
prop_data += sizeof(vd);

switch (vd) {
Expand Down Expand Up @@ -212,13 +214,13 @@ static int update_dt_node(u32 phandle, s32 scope)
return 0;
}

static int add_dt_node(u32 parent_phandle, u32 drc_index)
static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
{
struct device_node *dn;
struct device_node *parent_dn;
int rc;

parent_dn = of_find_node_by_phandle(parent_phandle);
parent_dn = of_find_node_by_phandle(be32_to_cpu(parent_phandle));
if (!parent_dn)
return -ENOENT;

Expand All @@ -237,7 +239,7 @@ static int add_dt_node(u32 parent_phandle, u32 drc_index)
int pseries_devicetree_update(s32 scope)
{
char *rtas_buf;
u32 *data;
__be32 *data;
int update_nodes_token;
int rc;

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

data = (u32 *)rtas_buf + 4;
while (*data & NODE_ACTION_MASK) {
data = (__be32 *)rtas_buf + 4;
while (be32_to_cpu(*data) & NODE_ACTION_MASK) {
int i;
u32 action = *data & NODE_ACTION_MASK;
int node_count = *data & NODE_COUNT_MASK;
u32 action = be32_to_cpu(*data) & NODE_ACTION_MASK;
u32 node_count = be32_to_cpu(*data) & NODE_COUNT_MASK;

data++;

for (i = 0; i < node_count; i++) {
u32 phandle = *data++;
u32 drc_index;
__be32 phandle = *data++;
__be32 drc_index;

switch (action) {
case DELETE_DT_NODE:
Expand Down

0 comments on commit f6ff041

Please sign in to comment.