Using SPCI memory sharing functions rather than MSG_SEND.

Bug: 132420445
Change-Id: I1d29ebfdf179c7a7c07223f8c027c22c055d333a
diff --git a/inc/hf/api.h b/inc/hf/api.h
index cfbff86..dacc889 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -60,3 +60,8 @@
 struct spci_value api_spci_features(uint32_t function_id);
 struct spci_value api_spci_run(spci_vm_id_t vm_id, spci_vcpu_index_t vcpu_idx,
 			       const struct vcpu *current, struct vcpu **next);
+struct spci_value api_spci_mem_send(uint32_t share_type, ipaddr_t address,
+				    uint32_t page_count,
+				    uint32_t remaining_fragment_count,
+				    uint32_t length, uint32_t handle,
+				    struct vcpu *current, struct vcpu **next);
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index f2455e2..5d217da 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -131,6 +131,33 @@
 		.arg4 = attributes});
 }
 
+static inline struct spci_value spci_mem_donate(
+	uint32_t remaining_fragment_count, uint32_t length, uint32_t handle)
+{
+	return spci_call((struct spci_value){.func = SPCI_MEM_DONATE_32,
+					     .arg3 = remaining_fragment_count,
+					     .arg4 = length,
+					     .arg5 = handle});
+}
+
+static inline struct spci_value spci_mem_lend(uint32_t remaining_fragment_count,
+					      uint32_t length, uint32_t handle)
+{
+	return spci_call((struct spci_value){.func = SPCI_MEM_LEND_32,
+					     .arg3 = remaining_fragment_count,
+					     .arg4 = length,
+					     .arg5 = handle});
+}
+
+static inline struct spci_value spci_mem_share(
+	uint32_t remaining_fragment_count, uint32_t length, uint32_t handle)
+{
+	return spci_call((struct spci_value){.func = SPCI_MEM_SHARE_32,
+					     .arg3 = remaining_fragment_count,
+					     .arg4 = length,
+					     .arg5 = handle});
+}
+
 /**
  * Called by secondary VMs to receive a message. This will block until a message
  * is received.
diff --git a/inc/vmapi/hf/spci.h b/inc/vmapi/hf/spci.h
index 12600c1..e42c8d5 100644
--- a/inc/vmapi/hf/spci.h
+++ b/inc/vmapi/hf/spci.h
@@ -43,6 +43,9 @@
 #define SPCI_MSG_SEND_32              0x8400006E
 #define SPCI_MSG_SEND_DIRECT_REQ_32   0x8400006F
 #define SPCI_MSG_SEND_DIRECT_RESP_32  0x84000070
+#define SPCI_MEM_DONATE_32            0x84000071
+#define SPCI_MEM_LEND_32              0x84000072
+#define SPCI_MEM_SHARE_32             0x84000073
 
 /* SPCI error codes. */
 #define SPCI_NOT_SUPPORTED      INT32_C(-1)
diff --git a/src/api.c b/src/api.c
index d8ced97..405b784 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1456,3 +1456,96 @@
 		return spci_error(SPCI_NOT_SUPPORTED);
 	}
 }
+
+struct spci_value api_spci_mem_send(uint32_t share_type, ipaddr_t address,
+				    uint32_t page_count,
+				    uint32_t remaining_fragment_count,
+				    uint32_t length, uint32_t handle,
+				    struct vcpu *current, struct vcpu **next)
+{
+	struct vm *from = current->vm;
+	struct vm *to;
+	const void *from_msg;
+	uint32_t message_buffer_size;
+	struct spci_memory_region *memory_region;
+	struct two_vm_locked vm_to_from_lock;
+	struct spci_value ret;
+
+	if (ipa_addr(address) != 0 || page_count != 0) {
+		/*
+		 * Hafnium only supports passing the descriptor in the TX
+		 * mailbox.
+		 */
+		return spci_error(SPCI_INVALID_PARAMETERS);
+	}
+
+	if (handle == 0 && remaining_fragment_count != 0) {
+		/* Handle is required if there are multiple fragments. */
+		return spci_error(SPCI_INVALID_PARAMETERS);
+	}
+
+	/*
+	 * Check that the sender has configured its send buffer. If the TX
+	 * mailbox at from_msg is configured (i.e. from_msg != NULL) then it can
+	 * be safely accessed after releasing the lock since the TX mailbox
+	 * address can only be configured once.
+	 */
+	sl_lock(&from->lock);
+	from_msg = from->mailbox.send;
+	sl_unlock(&from->lock);
+
+	if (from_msg == NULL) {
+		return spci_error(SPCI_INVALID_PARAMETERS);
+	}
+
+	/*
+	 * Copy the memory region descriptor to an internal buffer, so that the
+	 * sender can't change it underneath us.
+	 */
+	memory_region =
+		(struct spci_memory_region *)cpu_get_buffer(current->cpu->id);
+	message_buffer_size = cpu_get_buffer_size(current->cpu->id);
+	if (length > HF_MAILBOX_SIZE || length > message_buffer_size) {
+		return spci_error(SPCI_INVALID_PARAMETERS);
+	}
+	memcpy_s(memory_region, message_buffer_size, from_msg, length);
+
+	/* The sender must match the caller. */
+	if (memory_region->sender != from->id) {
+		return spci_error(SPCI_INVALID_PARAMETERS);
+	}
+
+	if (memory_region->attribute_count != 1) {
+		/* Hafnium doesn't support multi-way memory sharing for now. */
+		return spci_error(SPCI_NOT_SUPPORTED);
+	}
+
+	/*
+	 * Ensure that the receiver VM exists and isn't the same as the sender.
+	 */
+	to = vm_find(memory_region->attributes[0].receiver);
+	if (to == NULL || to == from) {
+		return spci_error(SPCI_INVALID_PARAMETERS);
+	}
+
+	vm_to_from_lock = vm_lock_both(to, from);
+
+	if (msg_receiver_busy(vm_to_from_lock.vm1, from, false)) {
+		ret = spci_error(SPCI_BUSY);
+		goto out;
+	}
+
+	ret = spci_msg_handle_architected_message(
+		vm_to_from_lock.vm1, vm_to_from_lock.vm2, memory_region, length,
+		share_type, &api_page_pool);
+
+	if (ret.func == SPCI_SUCCESS_32) {
+		deliver_msg(vm_to_from_lock.vm1, from->id, current, next);
+	}
+
+out:
+	vm_unlock(&vm_to_from_lock.vm1);
+	vm_unlock(&vm_to_from_lock.vm2);
+
+	return ret;
+}
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index 65aef52..b730cf3 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -366,6 +366,24 @@
 		*args = api_spci_run(spci_vm_id(*args), spci_vcpu_index(*args),
 				     current(), next);
 		return true;
+	case SPCI_MEM_DONATE_32:
+		*args = api_spci_mem_send(SPCI_MSG_SEND_LEGACY_MEMORY_DONATE,
+					  ipa_init(args->arg1), args->arg2,
+					  args->arg3, args->arg4, args->arg5,
+					  current(), next);
+		return true;
+	case SPCI_MEM_LEND_32:
+		*args = api_spci_mem_send(SPCI_MSG_SEND_LEGACY_MEMORY_LEND,
+					  ipa_init(args->arg1), args->arg2,
+					  args->arg3, args->arg4, args->arg5,
+					  current(), next);
+		return true;
+	case SPCI_MEM_SHARE_32:
+		*args = api_spci_mem_send(SPCI_MSG_SEND_LEGACY_MEMORY_SHARE,
+					  ipa_init(args->arg1), args->arg2,
+					  args->arg3, args->arg4, args->arg5,
+					  current(), next);
+		return true;
 	}
 
 	return false;
diff --git a/src/spci_architected_message.c b/src/spci_architected_message.c
index 06106d5..9d9c6c0 100644
--- a/src/spci_architected_message.c
+++ b/src/spci_architected_message.c
@@ -595,7 +595,7 @@
 
 	/* We only support a single recipient. */
 	if (memory_region->attribute_count != 1) {
-		return spci_error(SPCI_INVALID_PARAMETERS);
+		return spci_error(SPCI_NOT_SUPPORTED);
 	}
 
 	/* The recipient must match the message recipient. */
diff --git a/test/vmapi/primary_with_secondaries/memory_sharing.c b/test/vmapi/primary_with_secondaries/memory_sharing.c
index fd742f0..d930a48 100644
--- a/test/vmapi/primary_with_secondaries/memory_sharing.c
+++ b/test/vmapi/primary_with_secondaries/memory_sharing.c
@@ -32,7 +32,8 @@
  * Helper function to test sending memory in the different configurations.
  */
 static void check_cannot_send_memory(
-	struct mailbox_buffers mb, uint32_t mode,
+	struct mailbox_buffers mb,
+	struct spci_value (*send_function)(uint32_t, uint32_t, uint32_t),
 	struct spci_memory_region_constituent constituents[],
 	int constituent_count, int32_t avoid_vm)
 
@@ -75,9 +76,7 @@
 							cacheability[l],
 							shareability[k]);
 					EXPECT_SPCI_ERROR(
-						spci_msg_send(HF_PRIMARY_VM_ID,
-							      vms[i], msg_size,
-							      mode),
+						send_function(0, msg_size, 0),
 						SPCI_INVALID_PARAMETERS);
 				}
 				for (l = 0; l < ARRAY_SIZE(device); ++l) {
@@ -92,9 +91,7 @@
 							device[l],
 							shareability[k]);
 					EXPECT_SPCI_ERROR(
-						spci_msg_send(HF_PRIMARY_VM_ID,
-							      vms[i], msg_size,
-							      mode),
+						send_function(0, msg_size, 0),
 						SPCI_INVALID_PARAMETERS);
 				}
 			}
@@ -111,8 +108,8 @@
 	int constituent_count, int32_t avoid_vm)
 
 {
-	check_cannot_send_memory(mb, SPCI_MSG_SEND_LEGACY_MEMORY_LEND,
-				 constituents, constituent_count, avoid_vm);
+	check_cannot_send_memory(mb, spci_mem_lend, constituents,
+				 constituent_count, avoid_vm);
 }
 
 /**
@@ -124,8 +121,8 @@
 	int constituent_count, int32_t avoid_vm)
 
 {
-	check_cannot_send_memory(mb, SPCI_MSG_SEND_LEGACY_MEMORY_SHARE,
-				 constituents, constituent_count, avoid_vm);
+	check_cannot_send_memory(mb, spci_mem_share, constituents,
+				 constituent_count, avoid_vm);
 }
 
 /**
@@ -152,10 +149,8 @@
 			constituent_count, 0, 0, SPCI_MEMORY_RW_X,
 			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
-		EXPECT_SPCI_ERROR(
-			spci_msg_send(HF_PRIMARY_VM_ID, vms[i], msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
-			SPCI_INVALID_PARAMETERS);
+		EXPECT_SPCI_ERROR(spci_mem_donate(0, msg_size, 0),
+				  SPCI_INVALID_PARAMETERS);
 	}
 }
 
@@ -218,10 +213,7 @@
 		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_share(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(run_res.func, SPCI_YIELD_32);
@@ -264,10 +256,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_share(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be returned. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -329,10 +318,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 	run_res = spci_run(SERVICE_VM1, 0);
 
 	/* Let the memory be returned. */
@@ -375,10 +361,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/*
 	 * Let the service access the memory, and try and fail to relinquish it.
@@ -410,10 +393,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be returned. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -451,10 +431,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be returned. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -489,10 +466,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be returned. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -505,10 +479,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Observe the service doesn't fault when accessing the memory. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -537,10 +508,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be returned. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -553,10 +521,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(exception_handler_receive_exception_count(&run_res, mb.recv),
@@ -661,10 +626,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(exception_handler_receive_exception_count(&run_res, mb.recv),
@@ -685,10 +647,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(exception_handler_receive_exception_count(&run_res, mb.recv),
@@ -727,10 +686,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(exception_handler_receive_exception_count(&run_res, mb.recv),
@@ -751,10 +707,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM1, 0);
 	/*
@@ -792,10 +745,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 	run_res = spci_run(SERVICE_VM1, 0);
 
 	/* Let the memory be returned. */
@@ -808,10 +758,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(exception_handler_receive_exception_count(&run_res, mb.recv),
@@ -849,10 +796,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be sent from VM1 to VM2. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -899,10 +843,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be received. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -953,10 +894,8 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_SPCI_ERROR(
-		spci_msg_send(HF_PRIMARY_VM_ID, HF_PRIMARY_VM_ID, msg_size,
-			      SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
-		SPCI_INVALID_PARAMETERS);
+	EXPECT_SPCI_ERROR(spci_mem_donate(0, msg_size, 0),
+			  SPCI_INVALID_PARAMETERS);
 }
 
 /**
@@ -979,10 +918,8 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_SPCI_ERROR(
-		spci_msg_send(HF_PRIMARY_VM_ID, HF_PRIMARY_VM_ID, msg_size,
-			      SPCI_MSG_SEND_LEGACY_MEMORY_LEND),
-		SPCI_INVALID_PARAMETERS);
+	EXPECT_SPCI_ERROR(spci_mem_lend(0, msg_size, 0),
+			  SPCI_INVALID_PARAMETERS);
 }
 
 /**
@@ -1005,10 +942,8 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_SPCI_ERROR(
-		spci_msg_send(HF_PRIMARY_VM_ID, HF_PRIMARY_VM_ID, msg_size,
-			      SPCI_MSG_SEND_LEGACY_MEMORY_SHARE),
-		SPCI_INVALID_PARAMETERS);
+	EXPECT_SPCI_ERROR(spci_mem_share(0, msg_size, 0),
+			  SPCI_INVALID_PARAMETERS);
 }
 
 /**
@@ -1036,8 +971,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_SPCI_ERROR(spci_msg_send(SERVICE_VM1, HF_PRIMARY_VM_ID, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
+	EXPECT_SPCI_ERROR(spci_mem_donate(0, msg_size, 0),
 			  SPCI_INVALID_PARAMETERS);
 
 	msg_size = spci_memory_region_init(
@@ -1045,8 +979,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_SPCI_ERROR(spci_msg_send(SERVICE_VM1, SERVICE_VM1, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
+	EXPECT_SPCI_ERROR(spci_mem_donate(0, msg_size, 0),
 			  SPCI_INVALID_PARAMETERS);
 
 	msg_size = spci_memory_region_init(
@@ -1054,8 +987,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_SPCI_ERROR(spci_msg_send(SERVICE_VM2, SERVICE_VM1, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
+	EXPECT_SPCI_ERROR(spci_mem_donate(0, msg_size, 0),
 			  SPCI_INVALID_PARAMETERS);
 
 	/* Successfully donate to VM1. */
@@ -1064,10 +996,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Receive and return memory from VM1. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1107,22 +1036,16 @@
 				SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 				SPCI_MEMORY_CACHE_WRITE_BACK,
 				SPCI_MEMORY_OUTER_SHAREABLE);
-			EXPECT_SPCI_ERROR(
-				spci_msg_send(
-					HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
-				SPCI_INVALID_PARAMETERS);
+			EXPECT_SPCI_ERROR(spci_mem_donate(0, msg_size, 0),
+					  SPCI_INVALID_PARAMETERS);
 			msg_size = spci_memory_region_init(
 				mb.send, HF_PRIMARY_VM_ID, SERVICE_VM1,
 				constituents, ARRAY_SIZE(constituents), 0, 0,
 				SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 				SPCI_MEMORY_CACHE_WRITE_BACK,
 				SPCI_MEMORY_OUTER_SHAREABLE);
-			EXPECT_SPCI_ERROR(
-				spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1,
-					      msg_size,
-					      SPCI_MSG_SEND_LEGACY_MEMORY_LEND),
-				SPCI_INVALID_PARAMETERS);
+			EXPECT_SPCI_ERROR(spci_mem_lend(0, msg_size, 0),
+					  SPCI_INVALID_PARAMETERS);
 		}
 	}
 }
@@ -1151,8 +1074,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_SPCI_ERROR(spci_msg_send(SERVICE_VM1, HF_PRIMARY_VM_ID, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY_LEND),
+	EXPECT_SPCI_ERROR(spci_mem_lend(0, msg_size, 0),
 			  SPCI_INVALID_PARAMETERS);
 
 	/* Lend memory to VM1. */
@@ -1161,10 +1083,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Receive and return memory from VM1. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1202,10 +1121,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be accessed. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1225,10 +1141,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be accessed. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1265,10 +1178,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_share(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be accessed. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1294,10 +1204,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_share(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be accessed. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1340,10 +1247,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_share(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be accessed. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1368,10 +1272,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_share(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be accessed. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1416,10 +1317,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Attempt to execute from memory. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1431,10 +1329,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_NX,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(exception_handler_receive_exception_count(&run_res, mb.recv),
@@ -1469,10 +1364,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RO_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Attempt to execute from memory. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1484,10 +1376,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RO_NX,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(exception_handler_receive_exception_count(&run_res, mb.recv),
@@ -1520,10 +1409,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be accessed. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1538,10 +1424,8 @@
 			ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
-		EXPECT_SPCI_ERROR(
-			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
-			SPCI_INVALID_PARAMETERS);
+		EXPECT_SPCI_ERROR(spci_mem_donate(0, msg_size, 0),
+				  SPCI_INVALID_PARAMETERS);
 	}
 
 	/* Ensure we can donate to the only borrower. */
@@ -1550,10 +1434,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 }
 
 /**
@@ -1583,10 +1464,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_share(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be accessed. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1605,10 +1483,8 @@
 			ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
-		EXPECT_SPCI_ERROR(
-			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
-			SPCI_INVALID_PARAMETERS);
+		EXPECT_SPCI_ERROR(spci_mem_donate(0, msg_size, 0),
+				  SPCI_INVALID_PARAMETERS);
 	}
 
 	/* Ensure we can donate to the only borrower. */
@@ -1617,10 +1493,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 }
 
 /**
@@ -1650,10 +1523,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be accessed. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1693,10 +1563,8 @@
 			ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RO_X,
 			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
-		EXPECT_SPCI_ERROR(
-			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY_LEND),
-			SPCI_INVALID_PARAMETERS);
+		EXPECT_SPCI_ERROR(spci_mem_lend(0, msg_size, 0),
+				  SPCI_INVALID_PARAMETERS);
 	}
 }
 
@@ -1726,10 +1594,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_share(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Let the memory be accessed. */
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -1759,10 +1624,8 @@
 			ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RO_X,
 			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
-		EXPECT_SPCI_ERROR(
-			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY_SHARE),
-			SPCI_INVALID_PARAMETERS);
+		EXPECT_SPCI_ERROR(spci_mem_share(0, msg_size, 0),
+				  SPCI_INVALID_PARAMETERS);
 	}
 }
 
@@ -1790,10 +1653,7 @@
 		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_REGION_FLAG_CLEAR,
 		SPCI_MEMORY_RO_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_share(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Check that it has been cleared. */
 	for (i = 0; i < PAGE_SIZE * 2; ++i) {
@@ -1834,10 +1694,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(exception_handler_receive_exception_count(&run_res, mb.recv),
@@ -1859,10 +1716,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM2, 0);
 	EXPECT_EQ(exception_handler_receive_exception_count(&run_res, mb.recv),
@@ -1902,10 +1756,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(exception_handler_receive_exception_count(&run_res, mb.recv),
@@ -1927,10 +1778,7 @@
 		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	run_res = spci_run(SERVICE_VM2, 0);
 	EXPECT_EQ(exception_handler_receive_exception_count(&run_res, mb.recv),
diff --git a/test/vmapi/primary_with_secondaries/services/memory.c b/test/vmapi/primary_with_secondaries/services/memory.c
index 34909cc..98553c0 100644
--- a/test/vmapi/primary_with_secondaries/services/memory.c
+++ b/test/vmapi/primary_with_secondaries/services/memory.c
@@ -80,10 +80,7 @@
 		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_REGION_FLAG_CLEAR,
 		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(hf_vm_get_id(), HF_PRIMARY_VM_ID, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	exception_setup(NULL, exception_handler_yield);
 
@@ -106,10 +103,7 @@
 		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_REGION_FLAG_CLEAR,
 		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(hf_vm_get_id(), HF_PRIMARY_VM_ID, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_lend(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	exception_setup(NULL, exception_handler_yield);
 
@@ -165,10 +159,7 @@
 			SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
 		EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
-		EXPECT_EQ(spci_msg_send(spci_msg_send_receiver(ret),
-					spci_msg_send_sender(ret), msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-				  .func,
+		EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func,
 			  SPCI_SUCCESS_32);
 
 		/*
@@ -281,10 +272,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
-	EXPECT_EQ(spci_msg_send(spci_msg_send_receiver(ret), SERVICE_VM2,
-				msg_size, SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Ensure that we are unable to modify memory any more. */
 	ptr[0] = 'c';
@@ -319,20 +307,15 @@
 		send_buf, SERVICE_VM1, HF_PRIMARY_VM_ID, &constituent, 1, 0, 0,
 		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(SERVICE_VM1, HF_PRIMARY_VM_ID, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Attempt to donate the memory to another VM. */
 	msg_size = spci_memory_region_init(
 		send_buf, hf_vm_get_id(), SERVICE_VM2, &constituent, 1, 0, 0,
 		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_SPCI_ERROR(
-		spci_msg_send(spci_msg_send_receiver(ret), SERVICE_VM2,
-			      msg_size, SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
-		SPCI_INVALID_PARAMETERS);
+	EXPECT_SPCI_ERROR(spci_mem_donate(0, msg_size, 0),
+			  SPCI_INVALID_PARAMETERS);
 
 	spci_yield();
 }
@@ -391,10 +374,7 @@
 		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_EQ(spci_msg_send(spci_msg_send_receiver(ret), HF_PRIMARY_VM_ID,
-				msg_size, SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Fail to donate the memory from the primary to VM2. */
 	msg_size = spci_memory_region_init(
@@ -403,8 +383,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
-	EXPECT_SPCI_ERROR(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
+	EXPECT_SPCI_ERROR(spci_mem_donate(0, msg_size, 0),
 			  SPCI_INVALID_PARAMETERS);
 	spci_yield();
 }
@@ -575,8 +554,7 @@
 		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_SPCI_ERROR(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY_LEND),
+	EXPECT_SPCI_ERROR(spci_mem_lend(0, msg_size, 0),
 			  SPCI_INVALID_PARAMETERS);
 
 	/* Ensure we cannot share from the primary to another secondary. */
@@ -586,8 +564,7 @@
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
-	EXPECT_SPCI_ERROR(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY_SHARE),
+	EXPECT_SPCI_ERROR(spci_mem_share(0, msg_size, 0),
 			  SPCI_INVALID_PARAMETERS);
 
 	spci_yield();
@@ -821,19 +798,15 @@
 			&constituent_copy, 1, 0, 0, SPCI_MEMORY_RW_X,
 			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
-		EXPECT_SPCI_ERROR(
-			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY_LEND),
-			SPCI_INVALID_PARAMETERS);
+		EXPECT_SPCI_ERROR(spci_mem_lend(0, msg_size, 0),
+				  SPCI_INVALID_PARAMETERS);
 		msg_size = spci_memory_region_init(
 			send_buf, HF_PRIMARY_VM_ID, SERVICE_VM2,
 			&constituent_copy, 1, 0, 0, SPCI_MEMORY_RW_X,
 			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
-		EXPECT_SPCI_ERROR(
-			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY_SHARE),
-			SPCI_INVALID_PARAMETERS);
+		EXPECT_SPCI_ERROR(spci_mem_share(0, msg_size, 0),
+				  SPCI_INVALID_PARAMETERS);
 	}
 
 	/* Return control to primary. */
diff --git a/test/vmapi/primary_with_secondaries/services/unmapped.c b/test/vmapi/primary_with_secondaries/services/unmapped.c
index 13d78c5..c956b0f 100644
--- a/test/vmapi/primary_with_secondaries/services/unmapped.c
+++ b/test/vmapi/primary_with_secondaries/services/unmapped.c
@@ -50,10 +50,7 @@
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	exception_setup(NULL, exception_handler_yield);
 
-	EXPECT_EQ(spci_msg_send(hf_vm_get_id(), HF_PRIMARY_VM_ID, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	*(volatile uint64_t *)(&pages[PAGE_SIZE - 6]);
 	FAIL("Exception not generated by invalid access.");
@@ -90,10 +87,7 @@
 
 	exception_setup(NULL, exception_handler_yield);
 
-	EXPECT_EQ(spci_msg_send(hf_vm_get_id(), HF_PRIMARY_VM_ID, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
-			  .func,
-		  SPCI_SUCCESS_32);
+	EXPECT_EQ(spci_mem_donate(0, msg_size, 0).func, SPCI_SUCCESS_32);
 
 	/* Branch to instruction whose 2 bytes are now in an unmapped page. */
 	f();