feat(indirect messaging): change mailbox state on RX buffer full

Mailbox state transitions from RECEIVED to READ when the VM gets
notification and RX buffer full is set.

Change-Id: Ib90acf4b2949e1164bd7325d6ce14c4d203a37a7
Signed-off-by: Federico Recanati <federico.recanati@arm.com>
diff --git a/inc/hf/vm.h b/inc/hf/vm.h
index 05cd547..356fc7f 100644
--- a/inc/hf/vm.h
+++ b/inc/hf/vm.h
@@ -29,9 +29,9 @@
  *
  * EMPTY is the initial state. The follow state transitions are possible:
  * * EMPTY => RECEIVED: message sent to the VM.
- * * RECEIVED => READ: secondary VM returns from FFA_MSG_WAIT or
- *   FFA_MSG_POLL, or primary VM returns from FFA_RUN with an FFA_MSG_SEND
- *   where the receiver is itself.
+ * * RECEIVED => READ: secondary VM receives an RX buffer full notification
+ *   or primary VM returns from FFA_RUN with an FFA_MSG_SEND where the receiver
+ *   is itself.
  * * READ => EMPTY: VM called FFA_RX_RELEASE.
  */
 enum mailbox_state {
diff --git a/src/vm.c b/src/vm.c
index 2c479f3..514c74c 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -779,9 +779,27 @@
 ffa_notifications_bitmap_t vm_notifications_framework_get_pending(
 	struct vm_locked vm_locked)
 {
-	assert(vm_locked.vm != NULL);
-	return vm_notifications_state_get_pending(
-		&vm_locked.vm->notifications.framework);
+	struct vm *vm = vm_locked.vm;
+	ffa_notifications_bitmap_t framework;
+	bool rx_buffer_full;
+
+	assert(vm != NULL);
+
+	framework = vm_notifications_state_get_pending(
+		&vm->notifications.framework);
+
+	/*
+	 * By retrieving an RX buffer full notification the buffer state
+	 * transitions from RECEIVED to READ; the VM is now the RX buffer
+	 * owner, can read it and is allowed to release it.
+	 */
+	rx_buffer_full = is_ffa_spm_buffer_full_notification(framework) ||
+			 is_ffa_hyp_buffer_full_notification(framework);
+	if (rx_buffer_full && vm->mailbox.state == MAILBOX_STATE_RECEIVED) {
+		vm->mailbox.state = MAILBOX_STATE_READ;
+	}
+
+	return framework;
 }
 
 static void vm_notifications_state_info_get(