diff mbox

powerpc: fixing endianness of flash_block_list in rtas_flash

Message ID 1406310462-23005-1-git-send-email-tlfalcon@linux.vnet.ibm.com (mailing list archive)
State Accepted
Headers show

Commit Message

Thomas Falcon July 25, 2014, 5:47 p.m. UTC
The function rtas_flash_firmware passes the address of a data structure,
flash_block_list, when making the update-flash-64-and-reboot rtas call.
While the endianness of the address is handled correctly, the endianness
of the data is not.  This patch ensures that the data in flash_block_list
is big endian when passed to rtas on little endian hosts.

Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/rtas_flash.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Michael Ellerman July 28, 2014, 3:35 a.m. UTC | #1
Hi Thomas,

On Fri, 2014-07-25 at 12:47 -0500, Thomas Falcon wrote:
> [PATCH] powerpc: fixing endianness of flash_block_list in rtas_flash

Minor nit, but the commit title should use the imperative mood, so eg:

  [PATCH] powerpc: Fix endianness of flash_block_list in rtas_flash

> The function rtas_flash_firmware passes the address of a data structure,
> flash_block_list, when making the update-flash-64-and-reboot rtas call.
> While the endianness of the address is handled correctly, the endianness
> of the data is not.  This patch ensures that the data in flash_block_list
> is big endian when passed to rtas on little endian hosts.

This looks good.

But you can do even better by changing the data types to be explicitly BE, so
eg. length should be __be64 I think.

Then if you build with "make C=2 CF=-D__CHECK_ENDIAN__" and have sparse
installed it will tell you when incorrectly assign from/to the BE types.

cheers
diff mbox

Patch

diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 658e89d..db2b482 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -611,17 +611,19 @@  static void rtas_flash_firmware(int reboot_type)
 	for (f = flist; f; f = next) {
 		/* Translate data addrs to absolute */
 		for (i = 0; i < f->num_blocks; i++) {
-			f->blocks[i].data = (char *)__pa(f->blocks[i].data);
+			f->blocks[i].data = (char *)cpu_to_be64(__pa(f->blocks[i].data));
 			image_size += f->blocks[i].length;
+			f->blocks[i].length = cpu_to_be64(f->blocks[i].length);
 		}
 		next = f->next;
 		/* Don't translate NULL pointer for last entry */
 		if (f->next)
-			f->next = (struct flash_block_list *)__pa(f->next);
+			f->next = (struct flash_block_list *)cpu_to_be64(__pa(f->next));
 		else
 			f->next = NULL;
 		/* make num_blocks into the version/length field */
 		f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
+		f->num_blocks = cpu_to_be64(f->num_blocks);
 	}
 
 	printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);