powerpc/pseries: Correct buffer parsing in update_dt_node()
authorNathan Fontenot <nfont@linux.vnet.ibm.com>
Wed, 24 Apr 2013 05:49:36 +0000 (05:49 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Fri, 26 Apr 2013 06:08:19 +0000 (16:08 +1000)
Correct parsing of the buffer returned from ibm,update-properties. The first
element is a length and the path to the property which is slightly different
from the list of properties in the buffer so we need to specifically
handle this.

Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/platforms/pseries/mobility.c

index 4c184ceb2450bab7690dce713c5e5c2b803be03c..3d01eee9ffb1fa724fdcbe838ad2df5c36709e02 100644 (file)
@@ -134,6 +134,7 @@ static int update_dt_node(u32 phandle, s32 scope)
        char *prop_data;
        char *rtas_buf;
        int update_properties_token;
+       u32 vd;
 
        update_properties_token = rtas_token("ibm,update-properties");
        if (update_properties_token == RTAS_UNKNOWN_SERVICE)
@@ -160,13 +161,24 @@ static int update_dt_node(u32 phandle, s32 scope)
 
                prop_data = rtas_buf + sizeof(*upwa);
 
-               for (i = 0; i < upwa->nprops; i++) {
+               /* The first element of the buffer is the path of the node
+                * being updated in the form of a 8 byte string length
+                * followed by the string. Skip past this to get to the
+                * properties being updated.
+                */
+               vd = *prop_data++;
+               prop_data += vd;
+
+               /* The path we skipped over is counted as one of the elements
+                * returned so start counting at one.
+                */
+               for (i = 1; i < upwa->nprops; i++) {
                        char *prop_name;
-                       u32 vd;
 
-                       prop_name = prop_data + 1;
+                       prop_name = prop_data;
                        prop_data += strlen(prop_name) + 1;
-                       vd = *prop_data++;
+                       vd = *(u32 *)prop_data;
+                       prop_data += sizeof(vd);
 
                        switch (vd) {
                        case 0x00000000: