Attempting to release the RX buffer twice is an error.

Bug: 132421502
Bug: 146208457
Change-Id: I714d46db326172bf914378224edce7464d7f22d9
diff --git a/inc/hf/vm.h b/inc/hf/vm.h
index 8d5727e..9fff714 100644
--- a/inc/hf/vm.h
+++ b/inc/hf/vm.h
@@ -30,6 +30,16 @@
 #define MAX_SMCS 32
 #define LOG_BUFFER_SIZE 256
 
+/**
+ * The state of an RX buffer.
+ *
+ * EMPTY is the initial state. The follow state transitions are possible:
+ * * EMPTY → RECEIVED: message sent to the VM.
+ * * RECEIVED → READ: secondary VM returns from SPCI_MSG_WAIT or
+ *   SPCI_MSG_POLL, or primary VM returns from SPCI_RUN with an SPCI_MSG_SEND
+ *   where the receiver is itself.
+ * * READ → EMPTY: VM called SPCI_RX_RELEASE.
+ */
 enum mailbox_state {
 	/** There is no message in the mailbox. */
 	MAILBOX_STATE_EMPTY,
diff --git a/src/api.c b/src/api.c
index f9f3ceb..a5d6ef8 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1235,9 +1235,6 @@
 	locked = vm_lock(vm);
 	switch (vm->mailbox.state) {
 	case MAILBOX_STATE_EMPTY:
-		ret = (struct spci_value){.func = SPCI_SUCCESS_32};
-		break;
-
 	case MAILBOX_STATE_RECEIVED:
 		ret = spci_error(SPCI_DENIED);
 		break;
diff --git a/test/linux/hftest_socket.c b/test/linux/hftest_socket.c
index a07e188..b25691f 100644
--- a/test/linux/hftest_socket.c
+++ b/test/linux/hftest_socket.c
@@ -25,6 +25,7 @@
 #include "vmapi/hf/transport.h"
 
 #include "test/hftest.h"
+#include "test/vmapi/spci.h"
 
 alignas(4096) uint8_t kstack[4096];
 
@@ -68,7 +69,7 @@
 	/* Set up the mailbox. */
 	spci_rxtx_map(send_addr, recv_addr);
 
-	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
+	EXPECT_SPCI_ERROR(spci_rx_release(), SPCI_DENIED);
 
 	/* Clean the context. */
 	ctx = hftest_get_context();
diff --git a/test/vmapi/primary_with_secondaries/mailbox.c b/test/vmapi/primary_with_secondaries/mailbox.c
index c58115a..8e2e67c 100644
--- a/test/vmapi/primary_with_secondaries/mailbox.c
+++ b/test/vmapi/primary_with_secondaries/mailbox.c
@@ -64,13 +64,13 @@
 }
 
 /**
- * Clearing an empty mailbox is a noop.
+ * Clearing an empty mailbox is an error.
  */
 TEST(mailbox, clear_empty)
 {
-	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
-	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
-	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
+	EXPECT_SPCI_ERROR(spci_rx_release(), SPCI_DENIED);
+	EXPECT_SPCI_ERROR(spci_rx_release(), SPCI_DENIED);
+	EXPECT_SPCI_ERROR(spci_rx_release(), SPCI_DENIED);
 }
 
 /**
diff --git a/test/vmapi/primary_with_secondaries/memory_sharing.c b/test/vmapi/primary_with_secondaries/memory_sharing.c
index ad92087..44b5c92 100644
--- a/test/vmapi/primary_with_secondaries/memory_sharing.c
+++ b/test/vmapi/primary_with_secondaries/memory_sharing.c
@@ -832,7 +832,7 @@
 	/* Let the memory be sent from VM1 to VM2. */
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
-	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_msg_send_receiver(run_res), SERVICE_VM2);
 
 	/* Receive memory in VM2. */
 	run_res = spci_run(SERVICE_VM2, 0);