SPCI: SPCI_MSG_RECV.

Morph the existing vmapi api_mailbox_receive onto
api_spci_msg_recv.

Change-Id: Ie78f8985cfc55509fcd71eece22d6397b52d717d
diff --git a/src/abi_test.cc b/src/abi_test.cc
index 12dde09..f8cefa5 100644
--- a/src/abi_test.cc
+++ b/src/abi_test.cc
@@ -37,18 +37,6 @@
 }
 
 /**
- * Simulate an uninitialized hf_mailbox_receive_return so it can be detected if
- * any uninitialized fields make their way into the encoded form which would
- * indicate a data leak.
- */
-struct hf_mailbox_receive_return dirty_mailbox_receive_return()
-{
-	struct hf_mailbox_receive_return res;
-	memset(&res, 0xc5, sizeof(res));
-	return res;
-}
-
-/**
  * Encode a preempted response without leaking.
  */
 TEST(abi, hf_vcpu_run_return_encode_preempted)
@@ -244,27 +232,4 @@
 	EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_ABORTED));
 }
 
-/**
- * Encode a mailbox receive response without leaking.
- */
-TEST(abi, hf_mailbox_receive_return_encode)
-{
-	struct hf_mailbox_receive_return res = dirty_mailbox_receive_return();
-	res.vm_id = 0x12345678;
-	res.size = 0xaabbccdd;
-	EXPECT_THAT(hf_mailbox_receive_return_encode(res),
-		    Eq(0xaabbccdd12345678));
-}
-
-/**
- * Decode a mailbox receive response.
- */
-TEST(abi, hf_mailbox_receive_return_decode)
-{
-	struct hf_mailbox_receive_return res =
-		hf_mailbox_receive_return_decode(0X8badf00d00ddba11);
-	EXPECT_THAT(res.vm_id, Eq(0X00ddba11));
-	EXPECT_THAT(res.size, Eq(0x8badf00d));
-}
-
 } /* namespace */
diff --git a/src/api.c b/src/api.c
index 1fdb54a..16620a1 100644
--- a/src/api.c
+++ b/src/api.c
@@ -395,13 +395,7 @@
 		 * be delivered directly.
 		 */
 		if (vcpu->vm->mailbox.state == mailbox_state_received) {
-			arch_regs_set_retval(
-				&vcpu->regs,
-				hf_mailbox_receive_return_encode((
-					struct hf_mailbox_receive_return){
-					.vm_id = vcpu->vm->mailbox.recv_from_id,
-					.size = vcpu->vm->mailbox.recv_bytes,
-				}));
+			arch_regs_set_retval(&vcpu->regs, SPCI_SUCCESS);
 			vcpu->vm->mailbox.state = mailbox_state_read;
 			break;
 		}
@@ -817,8 +811,6 @@
 	to_msg = to->mailbox.recv;
 	*to_msg = from_msg_replica;
 	memcpy(to_msg->payload, from->mailbox.send->payload, size);
-	to->mailbox.recv_bytes = size;
-	to->mailbox.recv_from_id = from->id;
 	primary_ret.message.vm_id = to->id;
 	ret = SPCI_SUCCESS;
 
@@ -851,21 +843,20 @@
  *
  * No new messages can be received until the mailbox has been cleared.
  */
-struct hf_mailbox_receive_return api_mailbox_receive(bool block,
-						     struct vcpu *current,
-						     struct vcpu **next)
+int32_t api_spci_msg_recv(uint32_t attributes, struct vcpu *current,
+			  struct vcpu **next)
 {
 	struct vm *vm = current->vm;
-	struct hf_mailbox_receive_return ret = {
-		.vm_id = HF_INVALID_VM_ID,
-	};
+	int32_t return_code;
+	bool block =
+		(attributes & SPCI_MSG_RECV_BLOCK_MASK) == SPCI_MSG_RECV_BLOCK;
 
 	/*
 	 * 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 ret;
+		return SPCI_INTERRUPTED;
 	}
 
 	sl_lock(&vm->lock);
@@ -873,17 +864,28 @@
 	/* Return pending messages without blocking. */
 	if (vm->mailbox.state == mailbox_state_received) {
 		vm->mailbox.state = mailbox_state_read;
-		ret.vm_id = vm->mailbox.recv_from_id;
-		ret.size = vm->mailbox.recv_bytes;
+		return_code = SPCI_SUCCESS;
+		goto out;
+	}
+
+	/* No pending message so fail if not allowed to block. */
+	if (!block) {
+		return_code = SPCI_RETRY;
 		goto out;
 	}
 
 	/*
-	 * No pending message so fail if not allowed to block. Don't block if
-	 * there are enabled and pending interrupts, to match behaviour of
-	 * wait_for_interrupt.
+	 * From this point onward this call can only be interrupted or a message
+	 * received. If a message is received the return value will be set at
+	 * that time to SPCI_SUCCESS.
 	 */
-	if (!block || current->interrupts.enabled_and_pending_count > 0) {
+	return_code = SPCI_INTERRUPTED;
+
+	/*
+	 * Don't block if there are enabled and pending interrupts, to match
+	 * behaviour of wait_for_interrupt.
+	 */
+	if (current->interrupts.enabled_and_pending_count > 0) {
 		goto out;
 	}
 
@@ -899,7 +901,7 @@
 out:
 	sl_unlock(&vm->lock);
 
-	return ret;
+	return return_code;
 }
 
 /**
diff --git a/src/arch/aarch64/handler.c b/src/arch/aarch64/handler.c
index e29ddf0..871a38e 100644
--- a/src/arch/aarch64/handler.c
+++ b/src/arch/aarch64/handler.c
@@ -437,9 +437,8 @@
 		ret.user_ret = api_spci_msg_send(arg1, current(), &ret.new);
 		break;
 
-	case HF_MAILBOX_RECEIVE:
-		ret.user_ret = hf_mailbox_receive_return_encode(
-			api_mailbox_receive(arg1, current(), &ret.new));
+	case SPCI_MSG_RECV_32:
+		ret.user_ret = api_spci_msg_recv(arg1, current(), &ret.new);
 		break;
 
 	case HF_MAILBOX_CLEAR: