Skip to contentSkip to conversation

kexec/ppc64 fix device tree endianess issues for memory attributes

PATCH Applied Laurent Dufour 2 participants 2 messages Jan 30, 2014 – Jan 31, 2014

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 kexec/ppc64 fix device tree endianess issues for memory attributes

All the attributes exposed in the device tree are in Big Endian format.

This patch add the byte swap operation for some entries which were not yet processed, including those fixed by the following kernel's patch :

https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-January/114720.html

To work on PPC64 Little Endian mode, kexec now requires that the kernel's patch mentioned above is applied on the kexecing kernel.

Tested on ppc64 LPAR (kexec/dump) and ppc64le in a Qemu/KVM guest (kexec)

Changes from v1 :
* add processing of the following entries :
- ibm,dynamic-reconfiguration-memory
- chosen/linux,kernel-end
- chosen/linux,crashkernel-base & size
- chosen/linux,memory-limit
- chosen/linux,htab-base & size
- linux,tce-base & size
- memory@/reg

---
 kexec/arch/ppc64/crashdump-ppc64.c |    9 ++++---
 kexec/arch/ppc64/kexec-ppc64.c     |   44 +++++++++++++++++++++++++++---------
 kexec/fs2dt.c                      |   19 ++++++++--------
 3 files changed, 48 insertions(+), 24 deletions(-)
kexec/arch/ppc64/crashdump-ppc64.c +5 -4
index e31dd6d..c0d575d 100644
@@ -146,12 +146,12 @@ static int get_dyn_reconf_crash_memory_ranges(void)
 			return -1;
 		}
 
-		start = ((uint64_t *)buf)[DRCONF_ADDR];
+		start = be64_to_cpu(((uint64_t *)buf)[DRCONF_ADDR]);
 		end = start + lmb_size;
 		if (start == 0 && end >= (BACKUP_SRC_END + 1))
 			start = BACKUP_SRC_END + 1;
 
-		flags = (*((uint32_t *)&buf[DRCONF_FLAGS]));
+		flags = be32_to_cpu((*((uint32_t *)&buf[DRCONF_FLAGS])));
 		/* skip this block if the reserved bit is set in flags (0x80)
 		   or if the block is not assigned to this partition (0x8) */
 		if ((flags & 0x80) || !(flags & 0x8))
@@ -252,8 +252,9 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
 				goto err;
 			}
 
-			start = ((unsigned long long *)buf)[0];
-			end = start + ((unsigned long long *)buf)[1];
+			start = be64_to_cpu(((unsigned long long *)buf)[0]);
+			end = start +
+				be64_to_cpu(((unsigned long long *)buf)[1]);
 			if (start == 0 && end >= (BACKUP_SRC_END + 1))
 				start = BACKUP_SRC_END + 1;
 
kexec/arch/ppc64/kexec-ppc64.c +33 -11

146 lines not on this page · raw message

kexec/fs2dt.c +10 -9
index 7202dc1..73c1fb9 100644
@@ -197,7 +197,7 @@ static void add_dyn_reconf_usable_mem_property__(int fd)
 			die("unrecoverable error: error reading \"%s\": %s\n",
 				pathname, strerror(errno));
 
-		base = (uint64_t) buf[0];
+		base = be64_to_cpu((uint64_t) buf[0]);
 		end = base + lmb_size;
 		if (~0ULL - base < end)
 			die("unrecoverable error: mem property overflow\n");
@@ -229,8 +229,8 @@ static void add_dyn_reconf_usable_mem_property__(int fd)
 						    " ranges.\n",
 						    ranges_size*8);
 				}
-				ranges[rlen++] = loc_base;
-				ranges[rlen++] = loc_end - loc_base;
+				ranges[rlen++] = cpu_to_be64(loc_base);
+				ranges[rlen++] = cpu_to_be64(loc_end - loc_base);
 				rngs_cnt++;
 			}
 		}
@@ -255,7 +255,7 @@ static void add_dyn_reconf_usable_mem_property__(int fd)
 			}
 		} else {
 			/* Store the count of (base, size) duple */
-			ranges[tmp_indx] = rngs_cnt;
+			ranges[tmp_indx] = cpu_to_be64((uint64_t) rngs_cnt);
 		}
 	}
 		
@@ -309,10 +309,11 @@ static void add_usable_mem_property(int fd, size_t len)
 		die("unrecoverable error: error reading \"%s\": %s\n",
 		    pathname, strerror(errno));
 
-	if (~0ULL - buf[0] < buf[1])
-		die("unrecoverable error: mem property overflow\n");
 	base = be64_to_cpu(buf[0]);
-	end = base + be64_to_cpu(buf[1]);
+	end = be64_to_cpu(buf[1]);
+	if (~0ULL - base < end)
+		die("unrecoverable error: mem property overflow\n");
+	end += base;
 
 	ranges = malloc(ranges_size * sizeof(*ranges));
 	if (!ranges)
@@ -342,8 +343,8 @@ static void add_usable_mem_property(int fd, size_t len)
 					    "%d bytes for ranges.\n",
 					    ranges_size*sizeof(*ranges));
 			}
-			ranges[rlen++] = loc_base;
-			ranges[rlen++] = loc_end - loc_base;
+			ranges[rlen++] = cpu_to_be64(loc_base);
+			ranges[rlen++] = cpu_to_be64(loc_end - loc_base);
 		}
 	}
 
Applied
#1 lore raw
Quoted 21 lines · Laurent Dufour

All the attributes exposed in the device tree are in Big Endian format.

This patch add the byte swap operation for some entries which were not yet processed, including those fixed by the following kernel's patch :

https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-January/114720.html

To work on PPC64 Little Endian mode, kexec now requires that the kernel's patch mentioned above is applied on the kexecing kernel.

Tested on ppc64 LPAR (kexec/dump) and ppc64le in a Qemu/KVM guest (kexec)

Changes from v1 :
* add processing of the following entries :
- ibm,dynamic-reconfiguration-memory
- chosen/linux,kernel-end
- chosen/linux,crashkernel-base & size
- chosen/linux,memory-limit
- chosen/linux,htab-base & size
- linux,tce-base & size
- memory@/reg

Quoted 1 line

Thanks, applied.

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec