diff mbox series

prd: Fix prd message queuing interface

Message ID 20191022112830.17065-1-hegdevasant@linux.vnet.ibm.com
State Accepted
Headers show
Series prd: Fix prd message queuing interface | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (d75e82dbfbb9443efeb3f9a5921ac23605aab469)
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot success Test snowpatch/job/snowpatch-skiboot on branch master
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot-dco success Signed-off-by present

Commit Message

Vasant Hegde Oct. 22, 2019, 11:28 a.m. UTC
OPAL_MSG_PRD interface can handle message size <= OPAL_MSG_FIXED_PARAMS_SIZE.
But kernel prd driver had a bug where it will not copy partial data to user
space. This will create problem as opal-prd daemon tries to read message
continuously.

Commit 9cae036fa fixed this issue by enhancing opal-prd to allocate bigger
message size based on device tree.

For backward compatability (new OPAL and old kernel/userspace) lets restrict
OPAL_MSG_PRD messaging interface to send upto 32 bytes data. This is fine
as most of the messages are less than 32 bytes except FSP - HBRT messages
...which is new feature.

Cc: Jeremy Kerr <jk@ozlabs.org>
Cc: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
---
 hw/prd.c | 46 ++++++++++++++++++++--------------------------
 1 file changed, 20 insertions(+), 26 deletions(-)

Comments

Oliver O'Halloran Nov. 8, 2019, 5:02 a.m. UTC | #1
On Tue, Oct 22, 2019 at 10:28 PM Vasant Hegde
<hegdevasant@linux.vnet.ibm.com> wrote:
>
> OPAL_MSG_PRD interface can handle message size <= OPAL_MSG_FIXED_PARAMS_SIZE.
> But kernel prd driver had a bug where it will not copy partial data to user
> space. This will create problem as opal-prd daemon tries to read message
> continuously.
>
> Commit 9cae036fa fixed this issue by enhancing opal-prd to allocate bigger
> message size based on device tree.
>
> For backward compatability (new OPAL and old kernel/userspace) lets restrict
> OPAL_MSG_PRD messaging interface to send upto 32 bytes data. This is fine
> as most of the messages are less than 32 bytes except FSP - HBRT messages
> ...which is new feature.
>
> Cc: Jeremy Kerr <jk@ozlabs.org>
> Cc: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>

Merged as 790a604e37206569506e3552dbf6b583656c7ab1
diff mbox series

Patch

diff --git a/hw/prd.c b/hw/prd.c
index d9198f0eb..9c4cb1f45 100644
--- a/hw/prd.c
+++ b/hw/prd.c
@@ -149,6 +149,22 @@  static void prd_msg_consumed(void *data, int status)
 	unlock(&events_lock);
 }
 
+/*
+ * OPAL_MSG_PRD interface can handle message size <= OPAL_MSG_FIXED_PARAMS_SIZE.
+ * But kernel prd driver had a bug where it will not copy partial data to user
+ * space. Use OPAL_MSG_PRD interface only if size is <= sizeof(opal_prg_msg).
+ */
+static inline int opal_queue_prd_msg(struct opal_prd_msg *msg)
+{
+	enum opal_msg_type msg_type = OPAL_MSG_PRD2;
+
+	if (be16_to_cpu(msg->hdr.size) <= 0x20)
+		msg_type = OPAL_MSG_PRD;
+
+	return _opal_queue_msg(msg_type, msg, prd_msg_consumed,
+			       be16_to_cpu(msg->hdr.size), msg);
+}
+
 static int populate_ipoll_msg(struct opal_prd_msg *msg, uint32_t proc)
 {
 	uint64_t ipoll_mask;
@@ -224,8 +240,7 @@  static void send_next_pending_event(void)
 	 * disabled then we shouldn't propagate PRD events to the host.
 	 */
 	if (prd_enabled) {
-		rc = _opal_queue_msg(OPAL_MSG_PRD, prd_msg, prd_msg_consumed,
-				     prd_msg->hdr.size, prd_msg);
+		rc = opal_queue_prd_msg(prd_msg);
 		if (!rc)
 			prd_msg_inuse = true;
 	}
@@ -327,7 +342,6 @@  void prd_fw_resp_fsp_response(int status)
 	uint64_t fw_resp_len_old;
 	int rc;
 	uint16_t hdr_size;
-	enum opal_msg_type msg_type = OPAL_MSG_PRD2;
 
 	lock(&events_lock);
 
@@ -348,16 +362,7 @@  void prd_fw_resp_fsp_response(int status)
 		prd_msg_fsp_req->hdr.size = cpu_to_be16(hdr_size);
 	}
 
-	/*
-	 * If prd message size is <= OPAL_MSG_FIXED_PARAMS_SIZE then use
-	 * OPAL_MSG_PRD to pass data to kernel. So that it works fine on
-	 * older kernel (which does not support OPAL_MSG_PRD2).
-	 */
-	if (prd_msg_fsp_req->hdr.size < OPAL_MSG_FIXED_PARAMS_SIZE)
-		msg_type = OPAL_MSG_PRD;
-
-	rc = _opal_queue_msg(msg_type, prd_msg_fsp_req, prd_msg_consumed,
-			     prd_msg_fsp_req->hdr.size, prd_msg_fsp_req);
+	rc = opal_queue_prd_msg(prd_msg_fsp_req);
 	if (!rc)
 		prd_msg_inuse = true;
 	unlock(&events_lock);
@@ -367,7 +372,6 @@  int prd_hbrt_fsp_msg_notify(void *data, u32 dsize)
 {
 	int size;
 	int rc = FSP_STATUS_GENERIC_FAILURE;
-	enum opal_msg_type msg_type = OPAL_MSG_PRD2;
 
 	if (!prd_enabled || !prd_active) {
 		prlog(PR_NOTICE, "PRD: %s: PRD daemon is not ready\n",
@@ -407,16 +411,7 @@  int prd_hbrt_fsp_msg_notify(void *data, u32 dsize)
 	prd_msg_fsp_notify->fw_notify.len = cpu_to_be64(dsize);
 	memcpy(&(prd_msg_fsp_notify->fw_notify.data), data, dsize);
 
-	/*
-	 * If prd message size is <= OPAL_MSG_FIXED_PARAMS_SIZE then use
-	 * OPAL_MSG_PRD to pass data to kernel. So that it works fine on
-	 * older kernel (which does not support OPAL_MSG_PRD2).
-	 */
-	if (prd_msg_fsp_notify->hdr.size < OPAL_MSG_FIXED_PARAMS_SIZE)
-		msg_type = OPAL_MSG_PRD;
-
-	rc = _opal_queue_msg(msg_type, prd_msg_fsp_notify,
-			     prd_msg_consumed, size, prd_msg_fsp_notify);
+	rc = opal_queue_prd_msg(prd_msg_fsp_notify);
 	if (!rc)
 		prd_msg_inuse = true;
 
@@ -625,8 +620,7 @@  static int prd_msg_handle_firmware_req(struct opal_prd_msg *msg)
 	}
 
 	if (!rc) {
-		rc = _opal_queue_msg(OPAL_MSG_PRD, prd_msg, prd_msg_consumed,
-				     prd_msg->hdr.size, prd_msg);
+		rc = opal_queue_prd_msg(prd_msg);
 		if (rc)
 			prd_msg_inuse = false;
 	} else {