Skip to contentSkip to conversation

powerpc/powernv: Fix endian issues with OPAL async code

PATCH In review Anton Blanchard 2 participants 3 messages Mar 27, 2014

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

PATCH 1/2 powerpc/powernv: Fix endian issues with OPAL async code

Byteswap struct opal_msg in one place instead of requiring all the callers to do it.

---

arch/powerpc/include/asm/opal.h +6 -0
Index: b/arch/powerpc/include/asm/opal.h
===================================================================
@@ -421,6 +421,12 @@ enum OpalSysparamPerm {
 	OPAL_SYSPARAM_RW        = (OPAL_SYSPARAM_READ | OPAL_SYSPARAM_WRITE),
 };
 
+struct raw_opal_msg {
+	__be32 msg_type;
+	__be32 reserved;
+	__be64 params[8];
+};
+
 struct opal_msg {
 	uint32_t msg_type;
 	uint32_t reserved;
arch/powerpc/platforms/powernv/opal.c +8 -1
Index: b/arch/powerpc/platforms/powernv/opal.c
===================================================================
@@ -288,9 +288,11 @@ static void opal_handle_message(void)
 	 * TODO: pre-allocate a message buffer depending on opal-msg-size
 	 * value in /proc/device-tree.
 	 */
+	static struct raw_opal_msg raw_msg;
 	static struct opal_msg msg;
+	int i;
 
-	ret = opal_get_msg(__pa(&msg), sizeof(msg));
+	ret = opal_get_msg(__pa(&raw_msg), sizeof(raw_msg));
 	/* No opal message pending. */
 	if (ret == OPAL_RESOURCE)
 		return;
@@ -302,6 +304,11 @@ static void opal_handle_message(void)
 		return;
 	}
 
+	msg.msg_type = be32_to_cpu(raw_msg.msg_type);
+	msg.reserved = be32_to_cpu(raw_msg.reserved);
+	for (i = 0; i < ARRAY_SIZE(raw_msg.params); i++)
+		msg.params[i] = be64_to_cpu(raw_msg.params[i]);
+
 	/* Sanity check */
 	if (msg.msg_type > OPAL_MSG_TYPE_MAX) {
 		pr_warning("%s: Unknown message type: %u\n",
#1 lore raw

PATCH 2/2 powerpc/powernv: Fix endian issues with sensor code

One OPAL call and one device tree property needed byte swapping.

---

arch/powerpc/platforms/powernv/opal-sensor.c +3 -1
Index: b/arch/powerpc/platforms/powernv/opal-sensor.c
===================================================================
@@ -33,6 +33,7 @@ int opal_get_sensor_data(u32 sensor_hndl
 {
 	int ret, token;
 	struct opal_msg msg;
+	__be32 data;
 
 	token = opal_async_get_token_interruptible();
 	if (token < 0) {
@@ -42,7 +43,7 @@ int opal_get_sensor_data(u32 sensor_hndl
 	}
 
 	mutex_lock(&opal_sensor_mutex);
-	ret = opal_sensor_read(sensor_hndl, token, sensor_data);
+	ret = opal_sensor_read(sensor_hndl, token, &data);
 	if (ret != OPAL_ASYNC_COMPLETION)
 		goto out_token;
 
@@ -53,6 +54,7 @@ int opal_get_sensor_data(u32 sensor_hndl
 		goto out_token;
 	}
 
+	*sensor_data = be32_to_cpu(data);
 	ret = msg.params[1];
 
 out_token:
arch/powerpc/include/asm/opal.h +1 -2
Index: b/arch/powerpc/include/asm/opal.h
===================================================================
@@ -886,8 +886,7 @@ int64_t opal_get_param(uint64_t token, u
 		uint64_t length);
 int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer,
 		uint64_t length);
-int64_t opal_sensor_read(uint32_t sensor_hndl, int token,
-		uint32_t *sensor_data);
+int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data);
 
 /* Internal functions */
 extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
drivers/hwmon/ibmpowernv.c +3 -4
Index: b/drivers/hwmon/ibmpowernv.c
===================================================================
@@ -471,7 +471,7 @@ static int __init powernv_hwmon_init(voi
 	struct device_node *opal, *np = NULL;
 	enum attributes attr_type;
 	enum sensors type;
-	const u32 *sensor_id;
+	u32 sensor_id;
 	u32 sensor_index;
 	int err;
 
@@ -497,14 +497,13 @@ static int __init powernv_hwmon_init(voi
 				&sensor_index))
 			continue;
 
-		sensor_id = of_get_property(np, "sensor-id", NULL);
-		if (!sensor_id) {
+		if (of_property_read_u32(np, "sensor-id", &sensor_id)) {
 			pr_info("%s: %s doesn't have sensor-id\n", __func__,
 					np->name);
 			continue;
 		}
 
-		err = powernv_sensor_init(*sensor_id, np, type, attr_type,
+		err = powernv_sensor_init(sensor_id, np, type, attr_type,
 				sensor_index);
 		if (err) {
 			of_node_put(opal);
#2 lore raw
In reply to Anton Blanchard
Quoted 2 lines · Anton Blanchard

Byteswap struct opal_msg in one place instead of requiring all the callers to do it.

This will clash with us making opal.h something clean and identical between OPAL and clients.

Can you rename the converted version instead ? (yeah I know, it suck to find a good name ...)

Cheers,
Ben.

Quoted 49 lines

---

Index: b/arch/powerpc/include/asm/opal.h
===================================================================

arch/powerpc/include/asm/opal.h +6 -0
@@ -421,6 +421,12 @@ enum OpalSysparamPerm {
 	OPAL_SYSPARAM_RW        = (OPAL_SYSPARAM_READ | OPAL_SYSPARAM_WRITE),
 };
 
+struct raw_opal_msg {
+	__be32 msg_type;
+	__be32 reserved;
+	__be64 params[8];
+};
+
 struct opal_msg {
 	uint32_t msg_type;
 	uint32_t reserved;

Index: b/arch/powerpc/platforms/powernv/opal.c
===================================================================

arch/powerpc/platforms/powernv/opal.c +8 -1
@@ -288,9 +288,11 @@ static void opal_handle_message(void)
 	 * TODO: pre-allocate a message buffer depending on opal-msg-size
 	 * value in /proc/device-tree.
 	 */
+	static struct raw_opal_msg raw_msg;
 	static struct opal_msg msg;
+	int i;
 
-	ret = opal_get_msg(__pa(&msg), sizeof(msg));
+	ret = opal_get_msg(__pa(&raw_msg), sizeof(raw_msg));
 	/* No opal message pending. */
 	if (ret == OPAL_RESOURCE)
 		return;
@@ -302,6 +304,11 @@ static void opal_handle_message(void)
 		return;
 	}
 
+	msg.msg_type = be32_to_cpu(raw_msg.msg_type);
+	msg.reserved = be32_to_cpu(raw_msg.reserved);
+	for (i = 0; i < ARRAY_SIZE(raw_msg.params); i++)
+		msg.params[i] = be64_to_cpu(raw_msg.params[i]);
+
 	/* Sanity check */
 	if (msg.msg_type > OPAL_MSG_TYPE_MAX) {
 		pr_warning("%s: Unknown message type: %u\n",