aboutsummaryrefslogtreecommitdiff
path: root/hw/prd.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/prd.c')
-rw-r--r--hw/prd.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/hw/prd.c b/hw/prd.c
index e775adb..87babd1 100644
--- a/hw/prd.c
+++ b/hw/prd.c
@@ -89,7 +89,7 @@ static void prd_msg_consumed(void *data)
uint8_t event = 0;
lock(&events_lock);
- switch (msg->type) {
+ switch (msg->hdr.type) {
case OPAL_PRD_MSG_TYPE_ATTN:
proc = msg->attn.proc;
@@ -169,19 +169,20 @@ static void send_pending_events(void)
prd_msg_inuse = true;
prd_msg.token = 0;
+ prd_msg.hdr.size = sizeof(prd_msg);
if (event & EVENT_ATTN) {
- prd_msg.type = OPAL_PRD_MSG_TYPE_ATTN;
+ prd_msg.hdr.type = OPAL_PRD_MSG_TYPE_ATTN;
populate_ipoll_msg(&prd_msg, proc);
event = EVENT_ATTN;
} else if (event & EVENT_OCC_ERROR) {
- prd_msg.type = OPAL_PRD_MSG_TYPE_OCC_ERROR;
+ prd_msg.hdr.type = OPAL_PRD_MSG_TYPE_OCC_ERROR;
prd_msg.occ_error.chip = proc;
event = EVENT_OCC_ERROR;
} else if (event & EVENT_OCC_RESET) {
- prd_msg.type = OPAL_PRD_MSG_TYPE_OCC_RESET;
+ prd_msg.hdr.type = OPAL_PRD_MSG_TYPE_OCC_RESET;
prd_msg.occ_reset.chip = proc;
event = EVENT_OCC_RESET;
@@ -325,13 +326,20 @@ static int64_t opal_prd_msg(struct opal_prd_msg *msg)
{
int rc;
- switch (msg->type) {
+ /* fini is a little special: the kernel (which may not have the entire
+ * opal_prd_msg definition) can send a FINI message, so we don't check
+ * the full size */
+ if (msg->hdr.size >= sizeof(struct opal_prd_msg_header) &&
+ msg->hdr.type == OPAL_PRD_MSG_TYPE_FINI)
+ return prd_msg_handle_fini();
+
+ if (msg->hdr.size != sizeof(*msg))
+ return OPAL_PARAMETER;
+
+ switch (msg->hdr.type) {
case OPAL_PRD_MSG_TYPE_INIT:
rc = prd_msg_handle_init(msg);
break;
- case OPAL_PRD_MSG_TYPE_FINI:
- rc = prd_msg_handle_fini();
- break;
case OPAL_PRD_MSG_TYPE_ATTN_ACK:
rc = prd_msg_handle_attn_ack(msg);
break;