Return message size in hf_vcpu_run_return for HF_VCPU_RUN_MESSAGE.

Bug: 141469322
Change-Id: I25ba5051af57718c0bf18aad3a22f129c9c859e6
diff --git a/driver/linux b/driver/linux
index 139759e..b331fa9 160000
--- a/driver/linux
+++ b/driver/linux
@@ -1 +1 @@
-Subproject commit 139759e994e7c1b782b2b1de02f6acd98917c804
+Subproject commit b331fa985153f8184530a4758ef289dd16923448
diff --git a/inc/vmapi/hf/abi.h b/inc/vmapi/hf/abi.h
index b7fd716..14c3fc6 100644
--- a/inc/vmapi/hf/abi.h
+++ b/inc/vmapi/hf/abi.h
@@ -94,6 +94,7 @@
 		} wake_up;
 		struct {
 			spci_vm_id_t vm_id;
+			uint32_t size;
 		} message;
 		struct {
 			uint64_t ns;
@@ -134,6 +135,7 @@
 		ret |= (uint64_t)res.wake_up.vcpu << 16;
 		break;
 	case HF_VCPU_RUN_MESSAGE:
+		ret |= (uint64_t)res.message.size << 32;
 		ret |= res.message.vm_id << 8;
 		break;
 	case HF_VCPU_RUN_WAIT_FOR_INTERRUPT:
@@ -163,7 +165,8 @@
 		ret.wake_up.vcpu = (res >> 16) & 0xffff;
 		break;
 	case HF_VCPU_RUN_MESSAGE:
-		ret.message.vm_id = res >> 8;
+		ret.message.size = res >> 32;
+		ret.message.vm_id = (res >> 8) & 0xffff;
 		break;
 	case HF_VCPU_RUN_WAIT_FOR_INTERRUPT:
 	case HF_VCPU_RUN_WAIT_FOR_MESSAGE:
diff --git a/src/abi_test.cc b/src/abi_test.cc
index 204472d..0668ce0 100644
--- a/src/abi_test.cc
+++ b/src/abi_test.cc
@@ -176,7 +176,8 @@
 	struct hf_vcpu_run_return res = dirty_vcpu_run_return();
 	res.code = HF_VCPU_RUN_MESSAGE;
 	res.message.vm_id = 0xf007;
-	EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0x0000000000f00705));
+	res.message.size = 0xcafe1971;
+	EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0xcafe197100f00705));
 }
 
 /**
@@ -188,6 +189,7 @@
 		hf_vcpu_run_return_decode(0x1123581314916205);
 	EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_MESSAGE));
 	EXPECT_THAT(res.message.vm_id, Eq(0x9162));
+	EXPECT_THAT(res.message.size, Eq(0x11235813));
 }
 
 /**
diff --git a/src/api.c b/src/api.c
index e7fb9cd..2034ae9 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1005,6 +1005,12 @@
 
 	/* Messages for the primary VM are delivered directly. */
 	if (to->id == HF_PRIMARY_VM_ID) {
+		/*
+		 * Only tell the primary VM the size if the message is for it,
+		 * to avoid leaking data about messages for other VMs.
+		 */
+		primary_ret.message.size = size;
+
 		to->mailbox.state = MAILBOX_STATE_READ;
 		*next = api_switch_to_primary(current, primary_ret,
 					      VCPU_STATE_READY);
diff --git a/test/linux/hftest_socket.c b/test/linux/hftest_socket.c
index 7caf1bb..ae69abb 100644
--- a/test/linux/hftest_socket.c
+++ b/test/linux/hftest_socket.c
@@ -85,6 +85,7 @@
 
 		/* Receive the packet. */
 		ret = spci_msg_wait();
+		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 		EXPECT_LE(spci_msg_send_size(ret), SPCI_MSG_PAYLOAD_MAX);
 
 		/* Echo the message back to the sender. */
diff --git a/test/vmapi/arch/aarch64/gicv3/timer_secondary.c b/test/vmapi/arch/aarch64/gicv3/timer_secondary.c
index 849101b..b21bd83 100644
--- a/test/vmapi/arch/aarch64/gicv3/timer_secondary.c
+++ b/test/vmapi/arch/aarch64/gicv3/timer_secondary.c
@@ -74,7 +74,7 @@
 	 */
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(recv_buffer->length, sizeof(expected_response));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response));
 	EXPECT_EQ(memcmp(recv_buffer->payload, expected_response,
 			 sizeof(expected_response)),
 		  0);
@@ -172,7 +172,7 @@
 
 	/* Once we wake it up it should get the timer interrupt and respond. */
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(recv_buffer->length, sizeof(expected_response));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response));
 	EXPECT_EQ(memcmp(recv_buffer->payload, expected_response,
 			 sizeof(expected_response)),
 		  0);
diff --git a/test/vmapi/primary_with_secondaries/interrupts.c b/test/vmapi/primary_with_secondaries/interrupts.c
index f5a8036..ae081d4 100644
--- a/test/vmapi/primary_with_secondaries/interrupts.c
+++ b/test/vmapi/primary_with_secondaries/interrupts.c
@@ -49,7 +49,7 @@
 	EXPECT_EQ(spci_msg_send(0), 0);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(expected_response));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response));
 	EXPECT_EQ(memcmp(mb.recv->payload, expected_response,
 			 sizeof(expected_response)),
 		  0);
@@ -77,7 +77,7 @@
 	hf_interrupt_inject(SERVICE_VM0, 0, EXTERNAL_INTERRUPT_ID_A);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(expected_response));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response));
 	EXPECT_EQ(memcmp(mb.recv->payload, expected_response,
 			 sizeof(expected_response)),
 		  0);
@@ -87,7 +87,7 @@
 	hf_interrupt_inject(SERVICE_VM0, 0, EXTERNAL_INTERRUPT_ID_A);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(expected_response));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response));
 	EXPECT_EQ(memcmp(mb.recv->payload, expected_response,
 			 sizeof(expected_response)),
 		  0);
@@ -115,7 +115,7 @@
 	hf_interrupt_inject(SERVICE_VM0, 0, EXTERNAL_INTERRUPT_ID_A);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(expected_response));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response));
 	EXPECT_EQ(memcmp(mb.recv->payload, expected_response,
 			 sizeof(expected_response)),
 		  0);
@@ -125,7 +125,7 @@
 	hf_interrupt_inject(SERVICE_VM0, 0, EXTERNAL_INTERRUPT_ID_B);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(expected_response_2));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response_2));
 	EXPECT_EQ(memcmp(mb.recv->payload, expected_response_2,
 			 sizeof(expected_response_2)),
 		  0);
@@ -155,7 +155,7 @@
 	hf_interrupt_inject(SERVICE_VM0, 0, EXTERNAL_INTERRUPT_ID_A);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(expected_response));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response));
 	EXPECT_EQ(memcmp(mb.recv->payload, expected_response,
 			 sizeof(expected_response)),
 		  0);
@@ -173,7 +173,7 @@
 	EXPECT_EQ(spci_msg_send(0), 0);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(expected_response_2));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response_2));
 	EXPECT_EQ(memcmp(mb.recv->payload, expected_response_2,
 			 sizeof(expected_response_2)),
 		  0);
@@ -211,7 +211,7 @@
 	EXPECT_EQ(spci_msg_send(0), 0);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(expected_response));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response));
 	EXPECT_EQ(memcmp(mb.recv->payload, expected_response,
 			 sizeof(expected_response)),
 		  0);
@@ -239,7 +239,7 @@
 	hf_interrupt_inject(SERVICE_VM0, 0, EXTERNAL_INTERRUPT_ID_A);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(expected_response));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response));
 	EXPECT_EQ(memcmp(mb.recv->payload, expected_response,
 			 sizeof(expected_response)),
 		  0);
@@ -267,7 +267,7 @@
 	hf_interrupt_inject(SERVICE_VM0, 0, EXTERNAL_INTERRUPT_ID_A);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(expected_response));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response));
 	EXPECT_EQ(memcmp(mb.recv->payload, expected_response,
 			 sizeof(expected_response)),
 		  0);
@@ -298,7 +298,7 @@
 	hf_interrupt_inject(SERVICE_VM0, 0, EXTERNAL_INTERRUPT_ID_A);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(message));
+	EXPECT_EQ(run_res.message.size, sizeof(message));
 	EXPECT_EQ(memcmp(mb.recv->payload, message, sizeof(message)), 0);
 	EXPECT_EQ(hf_mailbox_clear(), 0);
 }
diff --git a/test/vmapi/primary_with_secondaries/mailbox.c b/test/vmapi/primary_with_secondaries/mailbox.c
index adb4ba2..ca06bff 100644
--- a/test/vmapi/primary_with_secondaries/mailbox.c
+++ b/test/vmapi/primary_with_secondaries/mailbox.c
@@ -95,7 +95,7 @@
 	EXPECT_EQ(spci_msg_send(0), 0);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(message));
+	EXPECT_EQ(run_res.message.size, sizeof(message));
 	EXPECT_EQ(memcmp(mb.send->payload, message, sizeof(message)), 0);
 	EXPECT_EQ(hf_mailbox_clear(), 0);
 }
@@ -127,7 +127,7 @@
 		EXPECT_EQ(spci_msg_send(0), 0);
 		run_res = hf_vcpu_run(SERVICE_VM0, 0);
 		EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-		EXPECT_EQ(mb.recv->length, sizeof(message));
+		EXPECT_EQ(run_res.message.size, sizeof(message));
 		EXPECT_EQ(memcmp(mb.recv->payload, message, sizeof(message)),
 			  0);
 		EXPECT_EQ(hf_mailbox_clear(), 0);
@@ -176,7 +176,7 @@
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
 	EXPECT_EQ(run_res.message.vm_id, SERVICE_VM1);
-	EXPECT_EQ(mb.recv->length, 0);
+	EXPECT_EQ(run_res.message.size, 0);
 
 	/* Let SERVICE_VM1 forward the message. */
 	run_res = hf_vcpu_run(SERVICE_VM1, 0);
@@ -184,7 +184,7 @@
 
 	/* Ensure the message is intact. */
 	EXPECT_EQ(run_res.message.vm_id, HF_PRIMARY_VM_ID);
-	EXPECT_EQ(mb.recv->length, sizeof(message));
+	EXPECT_EQ(run_res.message.size, sizeof(message));
 	EXPECT_EQ(memcmp(mb.recv->payload, message, sizeof(message)), 0);
 	EXPECT_EQ(hf_mailbox_clear(), 0);
 }
@@ -262,7 +262,7 @@
 	EXPECT_EQ(spci_msg_send(0), 0);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(message));
+	EXPECT_EQ(run_res.message.size, sizeof(message));
 	EXPECT_EQ(memcmp(mb.recv->payload, message, sizeof(message)), 0);
 
 	/* Let secondary VM continue running so that it will wait again. */
@@ -299,7 +299,7 @@
 		1);
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(message));
+	EXPECT_EQ(run_res.message.size, sizeof(message));
 	EXPECT_EQ(memcmp(mb.recv->payload, message, sizeof(message)), 0);
 }
 
@@ -331,7 +331,7 @@
 	/* Receive a reply for the first message. */
 	run_res = hf_vcpu_run(SERVICE_VM0, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(message));
+	EXPECT_EQ(run_res.message.size, sizeof(message));
 	EXPECT_EQ(memcmp(mb.recv->payload, message, sizeof(message)), 0);
 
 	/* Run VM again so that it clears its mailbox. */
diff --git a/test/vmapi/primary_with_secondaries/run_race.c b/test/vmapi/primary_with_secondaries/run_race.c
index 63ba81d..7ba4d74 100644
--- a/test/vmapi/primary_with_secondaries/run_race.c
+++ b/test/vmapi/primary_with_secondaries/run_race.c
@@ -46,7 +46,7 @@
 
 		/* Break out if we received a message with non-zero length. */
 		if (run_res.code == HF_VCPU_RUN_MESSAGE &&
-		    mb->recv->length != 0) {
+		    run_res.message.size != 0) {
 			break;
 		}
 
@@ -55,7 +55,7 @@
 	}
 
 	/* Copies the contents of the received boolean to the return value. */
-	if (mb->recv->length == sizeof(ok)) {
+	if (run_res.message.size == sizeof(ok)) {
 		ok = *(bool *)mb->recv->payload;
 	}
 
diff --git a/test/vmapi/primary_with_secondaries/smp.c b/test/vmapi/primary_with_secondaries/smp.c
index 64e0739..de91d78 100644
--- a/test/vmapi/primary_with_secondaries/smp.c
+++ b/test/vmapi/primary_with_secondaries/smp.c
@@ -47,7 +47,7 @@
 	dlog("Run second vCPU for message\n");
 	run_res = hf_vcpu_run(SERVICE_VM2, 1);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(expected_response_1));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response_1));
 	EXPECT_EQ(memcmp(mb.recv->payload, expected_response_1,
 			 sizeof(expected_response_1)),
 		  0);
@@ -57,7 +57,7 @@
 	dlog("Run first vCPU for message\n");
 	run_res = hf_vcpu_run(SERVICE_VM2, 0);
 	EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
-	EXPECT_EQ(mb.recv->length, sizeof(expected_response_0));
+	EXPECT_EQ(run_res.message.size, sizeof(expected_response_0));
 	EXPECT_EQ(memcmp(mb.recv->payload, expected_response_0,
 			 sizeof(expected_response_0)),
 		  0);