Use new-style return values from spci_msg_wait and spci_msg_poll.

Bug: 141469322
Change-Id: Ib9815695537837f029c698c6966bad93c094e89e
diff --git a/inc/hf/api.h b/inc/hf/api.h
index cc45a05..ebc6b20 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -56,7 +56,8 @@
 
 spci_return_t api_spci_msg_send(uint32_t attributes, struct vcpu *current,
 				struct vcpu **next);
-int32_t api_spci_msg_recv(bool block, struct vcpu *current, struct vcpu **next);
+struct spci_value api_spci_msg_recv(bool block, struct vcpu *current,
+				    struct vcpu **next);
 void api_yield(struct vcpu *current, struct vcpu **next);
 struct spci_value api_spci_version(void);
 spci_return_t api_spci_share_memory(struct vm_locked to_locked,
diff --git a/inc/hf/arch/cpu.h b/inc/hf/arch/cpu.h
index f244a3c..5a97681 100644
--- a/inc/hf/arch/cpu.h
+++ b/inc/hf/arch/cpu.h
@@ -58,4 +58,4 @@
  * This function must only be called on an arch_regs that is known not be in use
  * by any other physical CPU.
  */
-void arch_regs_set_retval(struct arch_regs *r, uintreg_t v);
+void arch_regs_set_retval(struct arch_regs *r, struct spci_value v);
diff --git a/inc/hf/spci_internal.h b/inc/hf/spci_internal.h
index 3877283..8f2a500 100644
--- a/inc/hf/spci_internal.h
+++ b/inc/hf/spci_internal.h
@@ -63,6 +63,11 @@
 	return mode;
 }
 
+static inline struct spci_value spci_error(uint64_t error_code)
+{
+	return (struct spci_value){.func = SPCI_ERROR_32, .arg1 = error_code};
+}
+
 spci_return_t spci_msg_handle_architected_message(
 	struct vm_locked to_locked, struct vm_locked from_locked,
 	const struct spci_architected_message_header
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index b99f15b..a920a58 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -138,14 +138,13 @@
  * that a message becoming available is also treated like a wake-up event.
  *
  * Returns:
- *  - SPCI_SUCCESS if a message is successfully received.
- *  - SPCI_INTERRUPTED if the caller is the primary VM or an interrupt happened
- *    during the call.
- *  - SPCI_RETRY if there was no pending message, and `block` was false.
+ *  - SPCI_MSG_SEND if a message is successfully received.
+ *  - SPCI_ERROR SPCI_NOT_SUPPORTED if called from the primary VM.
+ *  - SPCI_ERROR SPCI_INTERRUPTED if an interrupt happened during the call.
  */
-static inline int32_t spci_msg_wait(void)
+static inline struct spci_value spci_msg_wait(void)
 {
-	return hf_call(SPCI_MSG_WAIT_32, 0, 0, 0);
+	return spci_call((struct spci_value){.func = SPCI_MSG_WAIT_32});
 }
 
 /**
@@ -155,14 +154,14 @@
  * The mailbox must be cleared before a new message can be received.
  *
  * Returns:
- *  - SPCI_SUCCESS if a message is successfully received.
- *  - SPCI_INTERRUPTED if the caller is the primary VM or an interrupt happened
- *    during the call.
- *  - SPCI_RETRY if there was no pending message, and `block` was false.
+ *  - SPCI_MSG_SEND if a message is successfully received.
+ *  - SPCI_ERROR SPCI_NOT_SUPPORTED if called from the primary VM.
+ *  - SPCI_ERROR SPCI_INTERRUPTED if an interrupt happened during the call.
+ *  - SPCI_ERROR SPCI_RETRY if there was no pending message.
  */
-static inline int32_t spci_msg_poll(void)
+static inline struct spci_value spci_msg_poll(void)
 {
-	return hf_call(SPCI_MSG_POLL_32, 0, 0, 0);
+	return spci_call((struct spci_value){.func = SPCI_MSG_POLL_32});
 }
 
 /**
diff --git a/inc/vmapi/hf/spci.h b/inc/vmapi/hf/spci.h
index 0883038..125380b 100644
--- a/inc/vmapi/hf/spci.h
+++ b/inc/vmapi/hf/spci.h
@@ -193,6 +193,21 @@
 	uint64_t arg7;
 };
 
+static inline spci_vm_id_t spci_msg_send_sender(struct spci_value args)
+{
+	return (args.arg1 >> 16) & 0xffff;
+}
+
+static inline spci_vm_id_t spci_msg_send_receiver(struct spci_value args)
+{
+	return args.arg1 & 0xffff;
+}
+
+static inline uint32_t spci_msg_send_size(struct spci_value args)
+{
+	return args.arg3;
+}
+
 /** SPCI common message header. */
 struct spci_message {
 	/*
diff --git a/src/api.c b/src/api.c
index 0db632a..d2cdd11 100644
--- a/src/api.c
+++ b/src/api.c
@@ -91,8 +91,10 @@
 	}
 
 	/* Set the return value for the primary VM's call to HF_VCPU_RUN. */
-	arch_regs_set_retval(&next->regs,
-			     hf_vcpu_run_return_encode(primary_ret));
+	arch_regs_set_retval(
+		&next->regs,
+		(struct spci_value){
+			.func = hf_vcpu_run_return_encode(primary_ret)});
 
 	/* Mark the current vcpu as waiting. */
 	sl_lock(&current->lock);
@@ -343,6 +345,19 @@
 }
 
 /**
+ * Constructs an SPCI_MSG_SEND value to return from a successful SPCI_MSG_POLL
+ * or SPCI_MSG_WAIT call.
+ */
+static struct spci_value spci_msg_recv_return(const struct vm *receiver)
+{
+	return (struct spci_value){
+		.func = SPCI_MSG_SEND_32,
+		.arg1 = receiver->mailbox.recv->source_vm_id << 16 |
+			receiver->id,
+		.arg3 = receiver->mailbox.recv->length};
+}
+
+/**
  * Prepares the vcpu to run by updating its state and fetching whether a return
  * value needs to be forced onto the vCPU.
  */
@@ -422,7 +437,8 @@
 		 * be delivered directly.
 		 */
 		if (vcpu->vm->mailbox.state == MAILBOX_STATE_RECEIVED) {
-			arch_regs_set_retval(&vcpu->regs, SPCI_SUCCESS);
+			arch_regs_set_retval(&vcpu->regs,
+					     spci_msg_recv_return(vcpu->vm));
 			vcpu->vm->mailbox.state = MAILBOX_STATE_READ;
 			break;
 		}
@@ -1037,17 +1053,18 @@
  *
  * No new messages can be received until the mailbox has been cleared.
  */
-int32_t api_spci_msg_recv(bool block, struct vcpu *current, struct vcpu **next)
+struct spci_value api_spci_msg_recv(bool block, struct vcpu *current,
+				    struct vcpu **next)
 {
 	struct vm *vm = current->vm;
-	int32_t return_code;
+	struct spci_value return_code;
 
 	/*
 	 * The primary VM will receive messages as a status code from running
 	 * vcpus and must not call this function.
 	 */
 	if (vm->id == HF_PRIMARY_VM_ID) {
-		return SPCI_INTERRUPTED;
+		return spci_error(SPCI_NOT_SUPPORTED);
 	}
 
 	sl_lock(&vm->lock);
@@ -1055,13 +1072,13 @@
 	/* Return pending messages without blocking. */
 	if (vm->mailbox.state == MAILBOX_STATE_RECEIVED) {
 		vm->mailbox.state = MAILBOX_STATE_READ;
-		return_code = SPCI_SUCCESS;
+		return_code = spci_msg_recv_return(vm);
 		goto out;
 	}
 
 	/* No pending message so fail if not allowed to block. */
 	if (!block) {
-		return_code = SPCI_RETRY;
+		return_code = spci_error(SPCI_RETRY);
 		goto out;
 	}
 
@@ -1070,7 +1087,7 @@
 	 * received. If a message is received the return value will be set at
 	 * that time to SPCI_SUCCESS.
 	 */
-	return_code = SPCI_INTERRUPTED;
+	return_code = spci_error(SPCI_INTERRUPTED);
 	if (api_spci_msg_recv_block_interrupted(current)) {
 		goto out;
 	}
diff --git a/src/arch/aarch64/cpu.c b/src/arch/aarch64/cpu.c
index 50b295e..0fe4e3e 100644
--- a/src/arch/aarch64/cpu.c
+++ b/src/arch/aarch64/cpu.c
@@ -21,6 +21,7 @@
 #include <stdint.h>
 
 #include "hf/addr.h"
+#include "hf/spci.h"
 #include "hf/std.h"
 
 #include "hypervisor/perfmon.h"
@@ -129,7 +130,14 @@
 	r->r[0] = arg;
 }
 
-void arch_regs_set_retval(struct arch_regs *r, uintreg_t v)
+void arch_regs_set_retval(struct arch_regs *r, struct spci_value v)
 {
-	r->r[0] = v;
+	r->r[0] = v.func;
+	r->r[1] = v.arg1;
+	r->r[2] = v.arg2;
+	r->r[3] = v.arg3;
+	r->r[4] = v.arg4;
+	r->r[5] = v.arg5;
+	r->r[6] = v.arg6;
+	r->r[7] = v.arg7;
 }
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index 26b5496..d58a600 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -320,10 +320,10 @@
 		args->func = api_spci_msg_send(args->arg1, current(), next);
 		return true;
 	case SPCI_MSG_WAIT_32:
-		args->func = api_spci_msg_recv(true, current(), next);
+		*args = api_spci_msg_recv(true, current(), next);
 		return true;
 	case SPCI_MSG_POLL_32:
-		args->func = api_spci_msg_recv(false, current(), next);
+		*args = api_spci_msg_recv(false, current(), next);
 		return true;
 	}
 
diff --git a/src/arch/fake/hypervisor/cpu.c b/src/arch/fake/hypervisor/cpu.c
index f5885fd..71d6f92 100644
--- a/src/arch/fake/hypervisor/cpu.c
+++ b/src/arch/fake/hypervisor/cpu.c
@@ -16,6 +16,8 @@
 
 #include "hf/arch/cpu.h"
 
+#include "hf/spci.h"
+
 void arch_irq_disable(void)
 {
 	/* TODO */
@@ -42,7 +44,14 @@
 	r->r[0] = arg;
 }
 
-void arch_regs_set_retval(struct arch_regs *r, uintreg_t v)
+void arch_regs_set_retval(struct arch_regs *r, struct spci_value v)
 {
-	r->r[0] = v;
+	r->r[0] = v.func;
+	r->r[1] = v.arg1;
+	r->r[2] = v.arg2;
+	r->r[3] = v.arg3;
+	r->r[4] = v.arg4;
+	r->r[5] = v.arg5;
+	r->r[6] = v.arg6;
+	r->r[7] = v.arg7;
 }
diff --git a/src/arch/fake/inc/hf/arch/types.h b/src/arch/fake/inc/hf/arch/types.h
index 8a0eccb..24e16ae 100644
--- a/src/arch/fake/inc/hf/arch/types.h
+++ b/src/arch/fake/inc/hf/arch/types.h
@@ -46,7 +46,7 @@
 
 /** Type to represent the register state of a VM.  */
 struct arch_regs {
-	uintreg_t r[5];
+	uintreg_t r[8];
 	cpu_id_t vcpu_id;
 	bool virtual_interrupt;
 };
diff --git a/test/hftest/service.c b/test/hftest/service.c
index 3031772..c04c253 100644
--- a/test/hftest/service.c
+++ b/test/hftest/service.c
@@ -82,6 +82,7 @@
 	struct memiter args;
 	hftest_test_fn service;
 	struct hftest_context *ctx;
+	struct spci_value ret;
 
 	/*
 	 * Initialize the stage-1 MMU and identity-map the entire address space.
@@ -102,8 +103,8 @@
 	hf_vm_configure(send_addr, recv_addr);
 
 	/* Receive the name of the service to run. */
-	spci_msg_wait();
-	memiter_init(&args, recv_msg->payload, recv_msg->length);
+	ret = spci_msg_wait();
+	memiter_init(&args, recv_msg->payload, spci_msg_send_size(ret));
 	service = find_service(&args);
 	hf_mailbox_clear();
 
diff --git a/test/linux/hftest_socket.c b/test/linux/hftest_socket.c
index 7a9d7f1..7caf1bb 100644
--- a/test/linux/hftest_socket.c
+++ b/test/linux/hftest_socket.c
@@ -79,26 +79,28 @@
 	ctx->memory_size = memory_size;
 
 	for (;;) {
+		struct spci_value ret;
 		struct spci_message *send_buf = (struct spci_message *)send;
 		struct spci_message *recv_buf = (struct spci_message *)recv;
 
 		/* Receive the packet. */
-		spci_msg_wait();
-		EXPECT_LE(recv_buf->length, SPCI_MSG_PAYLOAD_MAX);
+		ret = spci_msg_wait();
+		EXPECT_LE(spci_msg_send_size(ret), SPCI_MSG_PAYLOAD_MAX);
 
 		/* Echo the message back to the sender. */
 		memcpy_s(send_buf->payload, SPCI_MSG_PAYLOAD_MAX,
-			 recv_buf->payload, recv_buf->length);
+			 recv_buf->payload, spci_msg_send_size(ret));
 
 		/* Swap the socket's source and destination ports */
 		struct hf_msg_hdr *hdr = (struct hf_msg_hdr *)send_buf->payload;
 		swap(&(hdr->src_port), &(hdr->dst_port));
 
 		/* Swap the destination and source ids. */
-		spci_vm_id_t dst_id = recv_buf->source_vm_id;
-		spci_vm_id_t src_id = recv_buf->target_vm_id;
+		spci_vm_id_t dst_id = spci_msg_send_sender(ret);
+		spci_vm_id_t src_id = spci_msg_send_receiver(ret);
 
-		spci_message_init(send_buf, recv_buf->length, dst_id, src_id);
+		spci_message_init(send_buf, spci_msg_send_size(ret), dst_id,
+				  src_id);
 
 		hf_mailbox_clear();
 		EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
diff --git a/test/vmapi/arch/aarch64/gicv3/services/common.c b/test/vmapi/arch/aarch64/gicv3/services/common.c
index d5d3cd2..1a10fbd 100644
--- a/test/vmapi/arch/aarch64/gicv3/services/common.c
+++ b/test/vmapi/arch/aarch64/gicv3/services/common.c
@@ -19,17 +19,19 @@
 #include "vmapi/hf/call.h"
 
 #include "hftest.h"
+
 /**
  * Try to receive a message from the mailbox, blocking if necessary, and
  * retrying if interrupted.
  */
-int32_t mailbox_receive_retry(void)
+struct spci_value mailbox_receive_retry(void)
 {
-	int32_t received;
+	struct spci_value received;
 
 	do {
 		received = spci_msg_wait();
-	} while (received == SPCI_INTERRUPTED);
+	} while (received.func == SPCI_ERROR_32 &&
+		 received.arg1 == SPCI_INTERRUPTED);
 
 	return received;
 }
diff --git a/test/vmapi/arch/aarch64/gicv3/services/common.h b/test/vmapi/arch/aarch64/gicv3/services/common.h
index 635fa0f..ced8baf 100644
--- a/test/vmapi/arch/aarch64/gicv3/services/common.h
+++ b/test/vmapi/arch/aarch64/gicv3/services/common.h
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-#include "vmapi/hf/call.h"
+#include "vmapi/hf/spci.h"
 
-int32_t mailbox_receive_retry(void);
+struct spci_value mailbox_receive_retry(void);
diff --git a/test/vmapi/arch/aarch64/gicv3/services/timer.c b/test/vmapi/arch/aarch64/gicv3/services/timer.c
index d99aa78..5d3dd2d 100644
--- a/test/vmapi/arch/aarch64/gicv3/services/timer.c
+++ b/test/vmapi/arch/aarch64/gicv3/services/timer.c
@@ -49,7 +49,7 @@
 	memcpy_s(SERVICE_SEND_BUFFER()->payload, SPCI_MSG_PAYLOAD_MAX, buffer,
 		 size);
 	spci_message_init(SERVICE_SEND_BUFFER(), size, HF_PRIMARY_VM_ID,
-			  SERVICE_RECV_BUFFER()->target_vm_id);
+			  hf_vm_get_id());
 	spci_msg_send(0);
 	dlog("secondary IRQ %d ended\n", interrupt_id);
 	event_send_local();
@@ -68,13 +68,13 @@
 		bool wfi, wfe, receive;
 		bool disable_interrupts;
 		uint32_t ticks;
-		mailbox_receive_retry();
+		struct spci_value ret = mailbox_receive_retry();
 
-		if (message_header->source_vm_id != HF_PRIMARY_VM_ID ||
-		    message_header->length != sizeof(timer_wfi_message)) {
+		if (spci_msg_send_sender(ret) != HF_PRIMARY_VM_ID ||
+		    spci_msg_send_size(ret) != sizeof(timer_wfi_message)) {
 			FAIL("Got unexpected message from VM %d, size %d.\n",
-			     message_header->source_vm_id,
-			     message_header->length);
+			     spci_msg_send_sender(ret),
+			     spci_msg_send_size(ret));
 		}
 
 		message = message_header->payload;
@@ -113,9 +113,10 @@
 				event_wait();
 			}
 		} else if (receive) {
-			int32_t res = spci_msg_wait();
+			struct spci_value res = spci_msg_wait();
 
-			EXPECT_EQ(res, SPCI_INTERRUPTED);
+			EXPECT_EQ(res.func, SPCI_ERROR_32);
+			EXPECT_EQ(res.arg1, SPCI_INTERRUPTED);
 		} else {
 			/* Busy wait until the timer fires. */
 			while (!timer_fired) {
diff --git a/test/vmapi/primary_with_secondaries/no_services.c b/test/vmapi/primary_with_secondaries/no_services.c
index 40da63d..0f60bed 100644
--- a/test/vmapi/primary_with_secondaries/no_services.c
+++ b/test/vmapi/primary_with_secondaries/no_services.c
@@ -166,8 +166,8 @@
  */
 TEST(hf_mailbox_receive, cannot_receive_from_primary_blocking)
 {
-	int32_t res = spci_msg_wait();
-	EXPECT_NE(res, SPCI_SUCCESS);
+	struct spci_value res = spci_msg_wait();
+	EXPECT_NE(res.func, SPCI_SUCCESS_32);
 }
 
 /**
@@ -175,6 +175,6 @@
  */
 TEST(hf_mailbox_receive, cannot_receive_from_primary_non_blocking)
 {
-	int32_t res = spci_msg_poll();
-	EXPECT_NE(res, SPCI_SUCCESS);
+	struct spci_value res = spci_msg_poll();
+	EXPECT_NE(res.func, SPCI_SUCCESS_32);
 }
diff --git a/test/vmapi/primary_with_secondaries/services/echo.c b/test/vmapi/primary_with_secondaries/services/echo.c
index a9d5b02..87695a8 100644
--- a/test/vmapi/primary_with_secondaries/services/echo.c
+++ b/test/vmapi/primary_with_secondaries/services/echo.c
@@ -25,15 +25,18 @@
 {
 	/* Loop, echo messages back to the sender. */
 	for (;;) {
-		spci_msg_wait();
+		struct spci_value ret = spci_msg_wait();
+		spci_vm_id_t target_vm_id = spci_msg_send_receiver(ret);
+		spci_vm_id_t source_vm_id = spci_msg_send_sender(ret);
 		struct spci_message *send_buf = SERVICE_SEND_BUFFER();
 		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 
+		ASSERT_EQ(ret.func, SPCI_MSG_SEND_32);
 		memcpy_s(send_buf->payload, SPCI_MSG_PAYLOAD_MAX,
-			 recv_buf->payload, recv_buf->length);
-		spci_message_init(SERVICE_SEND_BUFFER(), recv_buf->length,
-				  recv_buf->source_vm_id,
-				  recv_buf->target_vm_id);
+			 recv_buf->payload, spci_msg_send_size(ret));
+		spci_message_init(SERVICE_SEND_BUFFER(),
+				  spci_msg_send_size(ret), source_vm_id,
+				  target_vm_id);
 
 		hf_mailbox_clear();
 		spci_msg_send(0);
diff --git a/test/vmapi/primary_with_secondaries/services/echo_with_notification.c b/test/vmapi/primary_with_secondaries/services/echo_with_notification.c
index b32a6f6..ffd1e12 100644
--- a/test/vmapi/primary_with_secondaries/services/echo_with_notification.c
+++ b/test/vmapi/primary_with_secondaries/services/echo_with_notification.c
@@ -53,19 +53,19 @@
 
 	/* Loop, echo messages back to the sender. */
 	for (;;) {
-		spci_msg_wait();
-
 		struct spci_message *send_buf = SERVICE_SEND_BUFFER();
 		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
+		struct spci_value ret = spci_msg_wait();
+		spci_vm_id_t target_vm_id = spci_msg_send_receiver(ret);
+		spci_vm_id_t source_vm_id = spci_msg_send_sender(ret);
 
 		memcpy_s(send_buf->payload, SPCI_MSG_PAYLOAD_MAX,
-			 recv_buf->payload, recv_buf->length);
-		spci_message_init(send_buf, recv_buf->length,
-				  recv_buf->source_vm_id,
-				  recv_buf->target_vm_id);
+			 recv_buf->payload, spci_msg_send_size(ret));
+		spci_message_init(send_buf, spci_msg_send_size(ret),
+				  source_vm_id, target_vm_id);
 
 		while (spci_msg_send(SPCI_MSG_SEND_NOTIFY) != SPCI_SUCCESS) {
-			wait_for_vm(recv_buf->source_vm_id);
+			wait_for_vm(source_vm_id);
 		}
 
 		hf_mailbox_clear();
diff --git a/test/vmapi/primary_with_secondaries/services/interruptible.c b/test/vmapi/primary_with_secondaries/services/interruptible.c
index adc9b16..94ac007 100644
--- a/test/vmapi/primary_with_secondaries/services/interruptible.c
+++ b/test/vmapi/primary_with_secondaries/services/interruptible.c
@@ -51,13 +51,14 @@
  * Try to receive a message from the mailbox, blocking if necessary, and
  * retrying if interrupted.
  */
-int32_t mailbox_receive_retry()
+struct spci_value mailbox_receive_retry()
 {
-	int32_t received;
+	struct spci_value received;
 
 	do {
 		received = spci_msg_wait();
-	} while (received == SPCI_INTERRUPTED);
+	} while (received.func == SPCI_ERROR_32 &&
+		 received.arg1 == SPCI_INTERRUPTED);
 
 	return received;
 }
@@ -77,22 +78,25 @@
 		const char ping_message[] = "Ping";
 		const char enable_message[] = "Enable interrupt C";
 
-		mailbox_receive_retry();
-		if (recv_buf->source_vm_id == HF_PRIMARY_VM_ID &&
-		    recv_buf->length == sizeof(ping_message) &&
+		struct spci_value ret = mailbox_receive_retry();
+
+		ASSERT_EQ(ret.func, SPCI_MSG_SEND_32);
+		if (spci_msg_send_sender(ret) == HF_PRIMARY_VM_ID &&
+		    spci_msg_send_size(ret) == sizeof(ping_message) &&
 		    memcmp(recv_buf->payload, ping_message,
 			   sizeof(ping_message)) == 0) {
 			/* Interrupt ourselves */
 			hf_interrupt_inject(this_vm_id, 0, SELF_INTERRUPT_ID);
-		} else if (recv_buf->source_vm_id == HF_PRIMARY_VM_ID &&
-			   recv_buf->length == sizeof(enable_message) &&
+		} else if (spci_msg_send_sender(ret) == HF_PRIMARY_VM_ID &&
+			   spci_msg_send_size(ret) == sizeof(enable_message) &&
 			   memcmp(recv_buf->payload, enable_message,
 				  sizeof(enable_message)) == 0) {
 			/* Enable interrupt ID C. */
 			hf_interrupt_enable(EXTERNAL_INTERRUPT_ID_C, true);
 		} else {
 			dlog("Got unexpected message from VM %d, size %d.\n",
-			     recv_buf->source_vm_id, recv_buf->length);
+			     spci_msg_send_sender(ret),
+			     spci_msg_send_size(ret));
 			FAIL("Unexpected message");
 		}
 		hf_mailbox_clear();
diff --git a/test/vmapi/primary_with_secondaries/services/interruptible_echo.c b/test/vmapi/primary_with_secondaries/services/interruptible_echo.c
index 07a4cbc..560c47e 100644
--- a/test/vmapi/primary_with_secondaries/services/interruptible_echo.c
+++ b/test/vmapi/primary_with_secondaries/services/interruptible_echo.c
@@ -38,19 +38,21 @@
 	arch_irq_enable();
 
 	for (;;) {
-		uint32_t res = spci_msg_wait();
+		struct spci_value res = spci_msg_wait();
 		struct spci_message *message = SERVICE_SEND_BUFFER();
 		struct spci_message *recv_message = SERVICE_RECV_BUFFER();
 
 		/* Retry if interrupted but made visible with the yield. */
-		while (res == SPCI_INTERRUPTED) {
+		while (res.func == SPCI_ERROR_32 &&
+		       res.arg1 == SPCI_INTERRUPTED) {
 			spci_yield();
 			res = spci_msg_wait();
 		}
 
+		ASSERT_EQ(res.func, SPCI_MSG_SEND_32);
 		memcpy_s(message->payload, SPCI_MSG_PAYLOAD_MAX,
-			 recv_message->payload, recv_message->length);
-		spci_message_init(message, recv_message->length,
+			 recv_message->payload, spci_msg_send_size(res));
+		spci_message_init(message, spci_msg_send_size(res),
 				  HF_PRIMARY_VM_ID, SERVICE_VM0);
 
 		hf_mailbox_clear();
diff --git a/test/vmapi/primary_with_secondaries/services/memory.c b/test/vmapi/primary_with_secondaries/services/memory.c
index 8e4dc6f..bd12409 100644
--- a/test/vmapi/primary_with_secondaries/services/memory.c
+++ b/test/vmapi/primary_with_secondaries/services/memory.c
@@ -28,15 +28,17 @@
 {
 	/* Loop, writing message to the shared memory. */
 	for (;;) {
-		EXPECT_EQ(spci_msg_wait(), 0);
+		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
 		size_t i;
 
+		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
+
 		/* Check the memory was cleared. */
 		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 		ptr = *(uint8_t **)recv_buf->payload;
 		spci_message_init(SERVICE_SEND_BUFFER(), sizeof(ptr),
-				  recv_buf->source_vm_id, hf_vm_get_id());
+				  spci_msg_send_sender(ret), hf_vm_get_id());
 
 		for (int i = 0; i < PAGE_SIZE; ++i) {
 			ASSERT_EQ(ptr[i], 0);
@@ -60,9 +62,11 @@
 {
 	/* Loop, giving memory back to the sender. */
 	for (;;) {
-		spci_msg_wait();
+		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
 
+		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
+
 		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 		struct spci_message *send_buf = SERVICE_SEND_BUFFER();
 		struct spci_memory_region *memory_region =
@@ -82,7 +86,7 @@
 		hf_mailbox_clear();
 		/* Give the memory back and notify the sender. */
 		spci_memory_relinquish(
-			send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+			send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
 			memory_region->constituents, memory_region->count, 0);
 		spci_msg_send(0);
 
@@ -98,21 +102,23 @@
 {
 	/* Loop, giving memory back to the sender. */
 	for (;;) {
-		EXPECT_EQ(spci_msg_wait(), 0);
+		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
 
+		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
+
 		/* Check the memory was cleared. */
 		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 		ptr = *(uint8_t **)recv_buf->payload;
 		spci_message_init(SERVICE_SEND_BUFFER(), sizeof(ptr),
-				  recv_buf->source_vm_id, hf_vm_get_id());
+				  spci_msg_send_sender(ret), hf_vm_get_id());
 
 		for (int i = 0; i < PAGE_SIZE; ++i) {
 			ASSERT_EQ(ptr[i], 0);
 		}
 
 		/* Give the memory back and notify the sender. */
-		ASSERT_EQ(hf_share_memory(recv_buf->source_vm_id,
+		ASSERT_EQ(hf_share_memory(spci_msg_send_sender(ret),
 					  (hf_ipaddr_t)ptr, PAGE_SIZE,
 					  HF_MEMORY_GIVE),
 			  0);
@@ -179,13 +185,14 @@
 {
 	/* Loop, giving memory back to the sender. */
 	for (;;) {
-		EXPECT_EQ(spci_msg_wait(), 0);
+		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
-
 		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 		struct spci_message *send_buf = SERVICE_SEND_BUFFER();
 		struct spci_memory_region *memory_region =
 			spci_get_donated_memory_region(recv_buf);
+
+		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 		hf_mailbox_clear();
 
 		ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -197,7 +204,7 @@
 
 		/* Give the memory back and notify the sender. */
 		spci_memory_donate(
-			send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+			send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
 			memory_region->constituents, memory_region->count, 0);
 		spci_msg_send(0);
 
@@ -211,12 +218,13 @@
 
 TEST_SERVICE(spci_donate_check_upper_bound)
 {
-	EXPECT_EQ(spci_msg_wait(), 0);
+	struct spci_value ret = spci_msg_wait();
 	uint8_t *ptr;
-
 	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_memory_region *memory_region =
 		spci_get_donated_memory_region(recv_buf);
+
+	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 	hf_mailbox_clear();
 
 	ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -227,12 +235,13 @@
 
 TEST_SERVICE(spci_donate_check_lower_bound)
 {
-	EXPECT_EQ(spci_msg_wait(), 0);
+	struct spci_value ret = spci_msg_wait();
 	uint8_t *ptr;
-
 	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_memory_region *memory_region =
 		spci_get_donated_memory_region(recv_buf);
+
+	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 	hf_mailbox_clear();
 
 	ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -246,19 +255,20 @@
  */
 TEST_SERVICE(spci_donate_secondary_and_fault)
 {
-	EXPECT_EQ(spci_msg_wait(), 0);
+	struct spci_value ret = spci_msg_wait();
 	uint8_t *ptr;
-
 	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_message *send_buf = SERVICE_SEND_BUFFER();
 	struct spci_memory_region *memory_region =
 		spci_get_donated_memory_region(recv_buf);
+
+	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 	hf_mailbox_clear();
 
 	ptr = (uint8_t *)memory_region->constituents[0].address;
 
 	/* Donate memory to next VM. */
-	spci_memory_donate(send_buf, SERVICE_VM1, recv_buf->target_vm_id,
+	spci_memory_donate(send_buf, SERVICE_VM1, spci_msg_send_receiver(ret),
 			   memory_region->constituents, memory_region->count,
 			   0);
 	EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
@@ -274,14 +284,15 @@
  */
 TEST_SERVICE(spci_donate_twice)
 {
-	EXPECT_EQ(spci_msg_wait(), 0);
-
+	struct spci_value ret = spci_msg_wait();
 	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_message *send_buf = SERVICE_SEND_BUFFER();
 	struct spci_memory_region *memory_region =
 		spci_get_donated_memory_region(recv_buf);
 	struct spci_memory_region_constituent constituent =
 		memory_region->constituents[0];
+
+	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 	hf_mailbox_clear();
 
 	/* Yield to allow attempt to re donate from primary. */
@@ -293,7 +304,7 @@
 	EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
 
 	/* Attempt to donate the memory to another VM. */
-	spci_memory_donate(send_buf, SERVICE_VM1, recv_buf->target_vm_id,
+	spci_memory_donate(send_buf, SERVICE_VM1, spci_msg_send_receiver(ret),
 			   &constituent, memory_region->count, 0);
 	EXPECT_EQ(spci_msg_send(0), SPCI_INVALID_PARAMETERS);
 
@@ -307,12 +318,13 @@
 TEST_SERVICE(spci_memory_receive)
 {
 	for (;;) {
-		EXPECT_EQ(spci_msg_wait(), 0);
+		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
-
 		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 		struct spci_memory_region *memory_region =
 			spci_get_donated_memory_region(recv_buf);
+
+		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 		hf_mailbox_clear();
 
 		ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -330,18 +342,19 @@
  */
 TEST_SERVICE(spci_donate_invalid_source)
 {
-	EXPECT_EQ(spci_msg_wait(), 0);
-
+	struct spci_value ret = spci_msg_wait();
 	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_message *send_buf = SERVICE_SEND_BUFFER();
 	struct spci_memory_region *memory_region =
 		spci_get_donated_memory_region(recv_buf);
+
+	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 	hf_mailbox_clear();
 
 	/* Give the memory back and notify the sender. */
-	spci_memory_donate(send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
-			   memory_region->constituents, memory_region->count,
-			   0);
+	spci_memory_donate(
+		send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
+		memory_region->constituents, memory_region->count, 0);
 	EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
 
 	/* Fail to donate the memory from the primary to VM1. */
@@ -356,7 +369,7 @@
 {
 	/* Loop, giving memory back to the sender. */
 	for (;;) {
-		EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
 
 		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
@@ -366,6 +379,7 @@
 							      recv_buf)
 							      ->payload);
 
+		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 		ptr = (uint8_t *)memory_region->constituents[0].address;
 		/* Relevant information read, mailbox can be cleared. */
 		hf_mailbox_clear();
@@ -378,7 +392,7 @@
 		hf_mailbox_clear();
 		/* Give the memory back and notify the sender. */
 		spci_memory_relinquish(
-			send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+			send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
 			memory_region->constituents, memory_region->count, 0);
 		spci_msg_send(0);
 
@@ -396,13 +410,15 @@
 TEST_SERVICE(spci_memory_donate_relinquish)
 {
 	for (;;) {
-		EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
 
 		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 		struct spci_message *send_buf = SERVICE_SEND_BUFFER();
 		struct spci_memory_region *memory_region =
 			spci_get_donated_memory_region(recv_buf);
+
+		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 		hf_mailbox_clear();
 
 		ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -413,7 +429,7 @@
 		}
 		/* Give the memory back and notify the sender. */
 		spci_memory_relinquish(
-			send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+			send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
 			memory_region->constituents, memory_region->count, 0);
 		EXPECT_EQ(spci_msg_send(0), SPCI_INVALID_PARAMETERS);
 
@@ -429,24 +445,26 @@
  */
 TEST_SERVICE(spci_lend_invalid_source)
 {
-	EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+	struct spci_value ret = spci_msg_wait();
 
 	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_message *send_buf = SERVICE_SEND_BUFFER();
 	struct spci_memory_region *memory_region =
 		(struct spci_memory_region *)(spci_get_lend_descriptor(recv_buf)
 						      ->payload);
+
+	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 	hf_mailbox_clear();
 
 	/* Attempt to relinquish from primary VM. */
-	spci_memory_relinquish(send_buf, recv_buf->target_vm_id,
+	spci_memory_relinquish(send_buf, spci_msg_send_receiver(ret),
 			       HF_PRIMARY_VM_ID, memory_region->constituents,
 			       memory_region->count, 0);
 	EXPECT_EQ(spci_msg_send(0), SPCI_INVALID_PARAMETERS);
 
 	/* Give the memory back and notify the sender. */
 	spci_memory_relinquish(
-		send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+		send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
 		memory_region->constituents, memory_region->count, 0);
 	EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
 
@@ -465,7 +483,7 @@
 TEST_SERVICE(spci_memory_lend_relinquish_X)
 {
 	for (;;) {
-		EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+		struct spci_value ret = spci_msg_wait();
 		uint64_t *ptr;
 
 		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
@@ -474,6 +492,8 @@
 			(struct spci_memory_region *)(spci_get_lend_descriptor(
 							      recv_buf)
 							      ->payload);
+
+		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 		hf_mailbox_clear();
 
 		ptr = (uint64_t *)memory_region->constituents[0].address;
@@ -487,7 +507,7 @@
 
 		/* Release the memory again. */
 		spci_memory_relinquish(
-			send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+			send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
 			memory_region->constituents, memory_region->count, 0);
 		EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
 	}
@@ -499,7 +519,7 @@
 TEST_SERVICE(spci_memory_lend_relinquish_RW)
 {
 	for (;;) {
-		EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
 
 		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
@@ -508,6 +528,8 @@
 			(struct spci_memory_region *)(spci_get_lend_descriptor(
 							      recv_buf)
 							      ->payload);
+
+		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 		hf_mailbox_clear();
 
 		ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -526,7 +548,7 @@
 		}
 
 		spci_memory_relinquish(
-			send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+			send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
 			memory_region->constituents, memory_region->count, 0);
 		EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
 	}
@@ -537,13 +559,15 @@
  */
 TEST_SERVICE(spci_lend_check_lower_bound)
 {
-	EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+	struct spci_value ret = spci_msg_wait();
 	uint8_t *ptr;
 
 	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_memory_region *memory_region =
 		(struct spci_memory_region *)(spci_get_lend_descriptor(recv_buf)
 						      ->payload);
+
+	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 	hf_mailbox_clear();
 
 	ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -557,13 +581,15 @@
  */
 TEST_SERVICE(spci_lend_check_upper_bound)
 {
-	EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+	struct spci_value ret = spci_msg_wait();
 	uint8_t *ptr;
 
 	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_memory_region *memory_region =
 		(struct spci_memory_region *)(spci_get_lend_descriptor(recv_buf)
 						      ->payload);
+
+	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 	hf_mailbox_clear();
 
 	ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -574,7 +600,7 @@
 
 TEST_SERVICE(spci_memory_lend_twice)
 {
-	EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+	struct spci_value ret = spci_msg_wait();
 	uint8_t *ptr;
 
 	struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
@@ -582,6 +608,8 @@
 	struct spci_memory_region *memory_region =
 		(struct spci_memory_region *)(spci_get_lend_descriptor(recv_buf)
 						      ->payload);
+
+	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 	hf_mailbox_clear();
 
 	ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -612,7 +640,7 @@
 	}
 
 	spci_memory_relinquish(
-		send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+		send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
 		memory_region->constituents, memory_region->count, 0);
 	EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
 }
diff --git a/test/vmapi/primary_with_secondaries/services/receive_block.c b/test/vmapi/primary_with_secondaries/services/receive_block.c
index 1b03506..666754f 100644
--- a/test/vmapi/primary_with_secondaries/services/receive_block.c
+++ b/test/vmapi/primary_with_secondaries/services/receive_block.c
@@ -46,8 +46,9 @@
 	hf_interrupt_enable(EXTERNAL_INTERRUPT_ID_A, true);
 
 	for (i = 0; i < 10; ++i) {
-		int32_t res = spci_msg_wait();
-		EXPECT_EQ(res, SPCI_INTERRUPTED);
+		struct spci_value res = spci_msg_wait();
+		EXPECT_EQ(res.func, SPCI_ERROR_32);
+		EXPECT_EQ(res.arg1, SPCI_INTERRUPTED);
 	}
 
 	memcpy_s(SERVICE_SEND_BUFFER()->payload, SPCI_MSG_PAYLOAD_MAX, message,
diff --git a/test/vmapi/primary_with_secondaries/services/relay.c b/test/vmapi/primary_with_secondaries/services/relay.c
index 86eed79..1003699 100644
--- a/test/vmapi/primary_with_secondaries/services/relay.c
+++ b/test/vmapi/primary_with_secondaries/services/relay.c
@@ -36,17 +36,19 @@
 		uint32_t next_message_size;
 
 		/* Receive the message to relay. */
-		spci_msg_wait();
+		struct spci_value ret = spci_msg_wait();
+		ASSERT_EQ(ret.func, SPCI_MSG_SEND_32);
 
 		/* Prepare to relay the message. */
 		struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
 		struct spci_message *send_buf = SERVICE_SEND_BUFFER();
-		ASSERT_GE(recv_buf->length, sizeof(spci_vm_id_t));
+		ASSERT_GE(spci_msg_send_size(ret), sizeof(spci_vm_id_t));
 
 		chain = (spci_vm_id_t *)recv_buf->payload;
 		next_vm_id = le16toh(*chain);
 		next_message = chain + 1;
-		next_message_size = recv_buf->length - sizeof(spci_vm_id_t);
+		next_message_size =
+			spci_msg_send_size(ret) - sizeof(spci_vm_id_t);
 
 		/* Send the message to the next stage. */
 		memcpy_s(send_buf->payload, SPCI_MSG_PAYLOAD_MAX, next_message,
diff --git a/test/vmapi/primary_with_secondaries/services/spci_check.c b/test/vmapi/primary_with_secondaries/services/spci_check.c
index 1d626ba..3ce9a1f 100644
--- a/test/vmapi/primary_with_secondaries/services/spci_check.c
+++ b/test/vmapi/primary_with_secondaries/services/spci_check.c
@@ -29,7 +29,7 @@
 	struct spci_message expected_message = {
 		.flags = SPCI_MESSAGE_IMPDEF_MASK,
 		.length = sizeof(message),
-		.target_vm_id = SERVICE_VM0,
+		.target_vm_id = hf_vm_get_id(),
 		.source_vm_id = HF_PRIMARY_VM_ID,
 
 		/*
@@ -41,20 +41,14 @@
 	};
 
 	/* Wait for single message to be sent by the primary VM. */
-	spci_msg_wait();
+	struct spci_value ret = spci_msg_wait();
+
+	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 
 	/* Ensure message header has all fields correctly set. */
-	EXPECT_EQ(recv_buf->flags, expected_message.flags);
-	EXPECT_EQ(recv_buf->length, expected_message.length);
-	EXPECT_EQ(recv_buf->target_vm_id, expected_message.target_vm_id);
-	EXPECT_EQ(recv_buf->source_vm_id, expected_message.source_vm_id);
-
-	/* TODO: Padding fields may be set to MBZ in the next SPCI spec
-	 * versions. */
-	EXPECT_EQ(recv_buf->reserved_1, expected_message.reserved_1);
-	EXPECT_EQ(recv_buf->reserved_2, expected_message.reserved_2);
-
-	/* Ensure message header has all fields correctly set. */
+	EXPECT_EQ(spci_msg_send_size(ret), sizeof(message));
+	EXPECT_EQ(spci_msg_send_receiver(ret), hf_vm_get_id());
+	EXPECT_EQ(spci_msg_send_sender(ret), HF_PRIMARY_VM_ID);
 	EXPECT_EQ(memcmp(recv_buf, &expected_message, sizeof(expected_message)),
 		  0);
 
@@ -70,14 +64,17 @@
 	const char message[] = "this should be truncated";
 
 	/* Wait for single message to be sent by the primary VM. */
-	spci_msg_wait();
+	struct spci_value ret = spci_msg_wait();
+
+	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 
 	/* Verify the length is as expected. */
-	EXPECT_EQ(16, recv_buf->length);
+	EXPECT_EQ(16, spci_msg_send_size(ret));
 
 	/* Check only part of the message is sent correctly. */
 	EXPECT_NE(memcmp(recv_buf->payload, message, sizeof(message)), 0);
-	EXPECT_EQ(memcmp(recv_buf->payload, message, recv_buf->length), 0);
+	EXPECT_EQ(memcmp(recv_buf->payload, message, spci_msg_send_size(ret)),
+		  0);
 
 	spci_yield();
 }
@@ -85,7 +82,10 @@
 TEST_SERVICE(spci_recv_non_blocking)
 {
 	/* Wait for single message to be sent by the primary VM. */
-	EXPECT_EQ(spci_msg_poll(), SPCI_RETRY);
+	struct spci_value ret = spci_msg_poll();
+
+	EXPECT_EQ(ret.func, SPCI_ERROR_32);
+	EXPECT_EQ(ret.arg1, SPCI_RETRY);
 
 	spci_yield();
 }