Use new-style return values from spci_msg_wait and spci_msg_poll.
Bug: 141469322
Change-Id: Ib9815695537837f029c698c6966bad93c094e89e
diff --git a/inc/hf/api.h b/inc/hf/api.h
index cc45a05..ebc6b20 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -56,7 +56,8 @@
spci_return_t api_spci_msg_send(uint32_t attributes, struct vcpu *current,
struct vcpu **next);
-int32_t api_spci_msg_recv(bool block, struct vcpu *current, struct vcpu **next);
+struct spci_value api_spci_msg_recv(bool block, struct vcpu *current,
+ struct vcpu **next);
void api_yield(struct vcpu *current, struct vcpu **next);
struct spci_value api_spci_version(void);
spci_return_t api_spci_share_memory(struct vm_locked to_locked,
diff --git a/inc/hf/arch/cpu.h b/inc/hf/arch/cpu.h
index f244a3c..5a97681 100644
--- a/inc/hf/arch/cpu.h
+++ b/inc/hf/arch/cpu.h
@@ -58,4 +58,4 @@
* This function must only be called on an arch_regs that is known not be in use
* by any other physical CPU.
*/
-void arch_regs_set_retval(struct arch_regs *r, uintreg_t v);
+void arch_regs_set_retval(struct arch_regs *r, struct spci_value v);
diff --git a/inc/hf/spci_internal.h b/inc/hf/spci_internal.h
index 3877283..8f2a500 100644
--- a/inc/hf/spci_internal.h
+++ b/inc/hf/spci_internal.h
@@ -63,6 +63,11 @@
return mode;
}
+static inline struct spci_value spci_error(uint64_t error_code)
+{
+ return (struct spci_value){.func = SPCI_ERROR_32, .arg1 = error_code};
+}
+
spci_return_t spci_msg_handle_architected_message(
struct vm_locked to_locked, struct vm_locked from_locked,
const struct spci_architected_message_header
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index b99f15b..a920a58 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -138,14 +138,13 @@
* that a message becoming available is also treated like a wake-up event.
*
* Returns:
- * - SPCI_SUCCESS if a message is successfully received.
- * - SPCI_INTERRUPTED if the caller is the primary VM or an interrupt happened
- * during the call.
- * - SPCI_RETRY if there was no pending message, and `block` was false.
+ * - SPCI_MSG_SEND if a message is successfully received.
+ * - SPCI_ERROR SPCI_NOT_SUPPORTED if called from the primary VM.
+ * - SPCI_ERROR SPCI_INTERRUPTED if an interrupt happened during the call.
*/
-static inline int32_t spci_msg_wait(void)
+static inline struct spci_value spci_msg_wait(void)
{
- return hf_call(SPCI_MSG_WAIT_32, 0, 0, 0);
+ return spci_call((struct spci_value){.func = SPCI_MSG_WAIT_32});
}
/**
@@ -155,14 +154,14 @@
* The mailbox must be cleared before a new message can be received.
*
* Returns:
- * - SPCI_SUCCESS if a message is successfully received.
- * - SPCI_INTERRUPTED if the caller is the primary VM or an interrupt happened
- * during the call.
- * - SPCI_RETRY if there was no pending message, and `block` was false.
+ * - SPCI_MSG_SEND if a message is successfully received.
+ * - SPCI_ERROR SPCI_NOT_SUPPORTED if called from the primary VM.
+ * - SPCI_ERROR SPCI_INTERRUPTED if an interrupt happened during the call.
+ * - SPCI_ERROR SPCI_RETRY if there was no pending message.
*/
-static inline int32_t spci_msg_poll(void)
+static inline struct spci_value spci_msg_poll(void)
{
- return hf_call(SPCI_MSG_POLL_32, 0, 0, 0);
+ return spci_call((struct spci_value){.func = SPCI_MSG_POLL_32});
}
/**
diff --git a/inc/vmapi/hf/spci.h b/inc/vmapi/hf/spci.h
index 0883038..125380b 100644
--- a/inc/vmapi/hf/spci.h
+++ b/inc/vmapi/hf/spci.h
@@ -193,6 +193,21 @@
uint64_t arg7;
};
+static inline spci_vm_id_t spci_msg_send_sender(struct spci_value args)
+{
+ return (args.arg1 >> 16) & 0xffff;
+}
+
+static inline spci_vm_id_t spci_msg_send_receiver(struct spci_value args)
+{
+ return args.arg1 & 0xffff;
+}
+
+static inline uint32_t spci_msg_send_size(struct spci_value args)
+{
+ return args.arg3;
+}
+
/** SPCI common message header. */
struct spci_message {
/*
diff --git a/src/api.c b/src/api.c
index 0db632a..d2cdd11 100644
--- a/src/api.c
+++ b/src/api.c
@@ -91,8 +91,10 @@
}
/* Set the return value for the primary VM's call to HF_VCPU_RUN. */
- arch_regs_set_retval(&next->regs,
- hf_vcpu_run_return_encode(primary_ret));
+ arch_regs_set_retval(
+ &next->regs,
+ (struct spci_value){
+ .func = hf_vcpu_run_return_encode(primary_ret)});
/* Mark the current vcpu as waiting. */
sl_lock(¤t->lock);
@@ -343,6 +345,19 @@
}
/**
+ * Constructs an SPCI_MSG_SEND value to return from a successful SPCI_MSG_POLL
+ * or SPCI_MSG_WAIT call.
+ */
+static struct spci_value spci_msg_recv_return(const struct vm *receiver)
+{
+ return (struct spci_value){
+ .func = SPCI_MSG_SEND_32,
+ .arg1 = receiver->mailbox.recv->source_vm_id << 16 |
+ receiver->id,
+ .arg3 = receiver->mailbox.recv->length};
+}
+
+/**
* Prepares the vcpu to run by updating its state and fetching whether a return
* value needs to be forced onto the vCPU.
*/
@@ -422,7 +437,8 @@
* be delivered directly.
*/
if (vcpu->vm->mailbox.state == MAILBOX_STATE_RECEIVED) {
- arch_regs_set_retval(&vcpu->regs, SPCI_SUCCESS);
+ arch_regs_set_retval(&vcpu->regs,
+ spci_msg_recv_return(vcpu->vm));
vcpu->vm->mailbox.state = MAILBOX_STATE_READ;
break;
}
@@ -1037,17 +1053,18 @@
*
* No new messages can be received until the mailbox has been cleared.
*/
-int32_t api_spci_msg_recv(bool block, struct vcpu *current, struct vcpu **next)
+struct spci_value api_spci_msg_recv(bool block, struct vcpu *current,
+ struct vcpu **next)
{
struct vm *vm = current->vm;
- int32_t return_code;
+ struct spci_value return_code;
/*
* 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 SPCI_INTERRUPTED;
+ return spci_error(SPCI_NOT_SUPPORTED);
}
sl_lock(&vm->lock);
@@ -1055,13 +1072,13 @@
/* Return pending messages without blocking. */
if (vm->mailbox.state == MAILBOX_STATE_RECEIVED) {
vm->mailbox.state = MAILBOX_STATE_READ;
- return_code = SPCI_SUCCESS;
+ return_code = spci_msg_recv_return(vm);
goto out;
}
/* No pending message so fail if not allowed to block. */
if (!block) {
- return_code = SPCI_RETRY;
+ return_code = spci_error(SPCI_RETRY);
goto out;
}
@@ -1070,7 +1087,7 @@
* received. If a message is received the return value will be set at
* that time to SPCI_SUCCESS.
*/
- return_code = SPCI_INTERRUPTED;
+ return_code = spci_error(SPCI_INTERRUPTED);
if (api_spci_msg_recv_block_interrupted(current)) {
goto out;
}
diff --git a/src/arch/aarch64/cpu.c b/src/arch/aarch64/cpu.c
index 50b295e..0fe4e3e 100644
--- a/src/arch/aarch64/cpu.c
+++ b/src/arch/aarch64/cpu.c
@@ -21,6 +21,7 @@
#include <stdint.h>
#include "hf/addr.h"
+#include "hf/spci.h"
#include "hf/std.h"
#include "hypervisor/perfmon.h"
@@ -129,7 +130,14 @@
r->r[0] = arg;
}
-void arch_regs_set_retval(struct arch_regs *r, uintreg_t v)
+void arch_regs_set_retval(struct arch_regs *r, struct spci_value v)
{
- r->r[0] = v;
+ r->r[0] = v.func;
+ r->r[1] = v.arg1;
+ r->r[2] = v.arg2;
+ r->r[3] = v.arg3;
+ r->r[4] = v.arg4;
+ r->r[5] = v.arg5;
+ r->r[6] = v.arg6;
+ r->r[7] = v.arg7;
}
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index 26b5496..d58a600 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -320,10 +320,10 @@
args->func = api_spci_msg_send(args->arg1, current(), next);
return true;
case SPCI_MSG_WAIT_32:
- args->func = api_spci_msg_recv(true, current(), next);
+ *args = api_spci_msg_recv(true, current(), next);
return true;
case SPCI_MSG_POLL_32:
- args->func = api_spci_msg_recv(false, current(), next);
+ *args = api_spci_msg_recv(false, current(), next);
return true;
}
diff --git a/src/arch/fake/hypervisor/cpu.c b/src/arch/fake/hypervisor/cpu.c
index f5885fd..71d6f92 100644
--- a/src/arch/fake/hypervisor/cpu.c
+++ b/src/arch/fake/hypervisor/cpu.c
@@ -16,6 +16,8 @@
#include "hf/arch/cpu.h"
+#include "hf/spci.h"
+
void arch_irq_disable(void)
{
/* TODO */
@@ -42,7 +44,14 @@
r->r[0] = arg;
}
-void arch_regs_set_retval(struct arch_regs *r, uintreg_t v)
+void arch_regs_set_retval(struct arch_regs *r, struct spci_value v)
{
- r->r[0] = v;
+ r->r[0] = v.func;
+ r->r[1] = v.arg1;
+ r->r[2] = v.arg2;
+ r->r[3] = v.arg3;
+ r->r[4] = v.arg4;
+ r->r[5] = v.arg5;
+ r->r[6] = v.arg6;
+ r->r[7] = v.arg7;
}
diff --git a/src/arch/fake/inc/hf/arch/types.h b/src/arch/fake/inc/hf/arch/types.h
index 8a0eccb..24e16ae 100644
--- a/src/arch/fake/inc/hf/arch/types.h
+++ b/src/arch/fake/inc/hf/arch/types.h
@@ -46,7 +46,7 @@
/** Type to represent the register state of a VM. */
struct arch_regs {
- uintreg_t r[5];
+ uintreg_t r[8];
cpu_id_t vcpu_id;
bool virtual_interrupt;
};
diff --git a/test/hftest/service.c b/test/hftest/service.c
index 3031772..c04c253 100644
--- a/test/hftest/service.c
+++ b/test/hftest/service.c
@@ -82,6 +82,7 @@
struct memiter args;
hftest_test_fn service;
struct hftest_context *ctx;
+ struct spci_value ret;
/*
* Initialize the stage-1 MMU and identity-map the entire address space.
@@ -102,8 +103,8 @@
hf_vm_configure(send_addr, recv_addr);
/* Receive the name of the service to run. */
- spci_msg_wait();
- memiter_init(&args, recv_msg->payload, recv_msg->length);
+ ret = spci_msg_wait();
+ memiter_init(&args, recv_msg->payload, spci_msg_send_size(ret));
service = find_service(&args);
hf_mailbox_clear();
diff --git a/test/linux/hftest_socket.c b/test/linux/hftest_socket.c
index 7a9d7f1..7caf1bb 100644
--- a/test/linux/hftest_socket.c
+++ b/test/linux/hftest_socket.c
@@ -79,26 +79,28 @@
ctx->memory_size = memory_size;
for (;;) {
+ struct spci_value ret;
struct spci_message *send_buf = (struct spci_message *)send;
struct spci_message *recv_buf = (struct spci_message *)recv;
/* Receive the packet. */
- spci_msg_wait();
- EXPECT_LE(recv_buf->length, SPCI_MSG_PAYLOAD_MAX);
+ ret = spci_msg_wait();
+ EXPECT_LE(spci_msg_send_size(ret), SPCI_MSG_PAYLOAD_MAX);
/* Echo the message back to the sender. */
memcpy_s(send_buf->payload, SPCI_MSG_PAYLOAD_MAX,
- recv_buf->payload, recv_buf->length);
+ recv_buf->payload, spci_msg_send_size(ret));
/* Swap the socket's source and destination ports */
struct hf_msg_hdr *hdr = (struct hf_msg_hdr *)send_buf->payload;
swap(&(hdr->src_port), &(hdr->dst_port));
/* Swap the destination and source ids. */
- spci_vm_id_t dst_id = recv_buf->source_vm_id;
- spci_vm_id_t src_id = recv_buf->target_vm_id;
+ spci_vm_id_t dst_id = spci_msg_send_sender(ret);
+ spci_vm_id_t src_id = spci_msg_send_receiver(ret);
- spci_message_init(send_buf, recv_buf->length, dst_id, src_id);
+ spci_message_init(send_buf, spci_msg_send_size(ret), dst_id,
+ src_id);
hf_mailbox_clear();
EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
diff --git a/test/vmapi/arch/aarch64/gicv3/services/common.c b/test/vmapi/arch/aarch64/gicv3/services/common.c
index d5d3cd2..1a10fbd 100644
--- a/test/vmapi/arch/aarch64/gicv3/services/common.c
+++ b/test/vmapi/arch/aarch64/gicv3/services/common.c
@@ -19,17 +19,19 @@
#include "vmapi/hf/call.h"
#include "hftest.h"
+
/**
* Try to receive a message from the mailbox, blocking if necessary, and
* retrying if interrupted.
*/
-int32_t mailbox_receive_retry(void)
+struct spci_value mailbox_receive_retry(void)
{
- int32_t received;
+ struct spci_value received;
do {
received = spci_msg_wait();
- } while (received == SPCI_INTERRUPTED);
+ } while (received.func == SPCI_ERROR_32 &&
+ received.arg1 == SPCI_INTERRUPTED);
return received;
}
diff --git a/test/vmapi/arch/aarch64/gicv3/services/common.h b/test/vmapi/arch/aarch64/gicv3/services/common.h
index 635fa0f..ced8baf 100644
--- a/test/vmapi/arch/aarch64/gicv3/services/common.h
+++ b/test/vmapi/arch/aarch64/gicv3/services/common.h
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-#include "vmapi/hf/call.h"
+#include "vmapi/hf/spci.h"
-int32_t mailbox_receive_retry(void);
+struct spci_value mailbox_receive_retry(void);
diff --git a/test/vmapi/arch/aarch64/gicv3/services/timer.c b/test/vmapi/arch/aarch64/gicv3/services/timer.c
index d99aa78..5d3dd2d 100644
--- a/test/vmapi/arch/aarch64/gicv3/services/timer.c
+++ b/test/vmapi/arch/aarch64/gicv3/services/timer.c
@@ -49,7 +49,7 @@
memcpy_s(SERVICE_SEND_BUFFER()->payload, SPCI_MSG_PAYLOAD_MAX, buffer,
size);
spci_message_init(SERVICE_SEND_BUFFER(), size, HF_PRIMARY_VM_ID,
- SERVICE_RECV_BUFFER()->target_vm_id);
+ hf_vm_get_id());
spci_msg_send(0);
dlog("secondary IRQ %d ended\n", interrupt_id);
event_send_local();
@@ -68,13 +68,13 @@
bool wfi, wfe, receive;
bool disable_interrupts;
uint32_t ticks;
- mailbox_receive_retry();
+ struct spci_value ret = mailbox_receive_retry();
- if (message_header->source_vm_id != HF_PRIMARY_VM_ID ||
- message_header->length != sizeof(timer_wfi_message)) {
+ if (spci_msg_send_sender(ret) != HF_PRIMARY_VM_ID ||
+ spci_msg_send_size(ret) != sizeof(timer_wfi_message)) {
FAIL("Got unexpected message from VM %d, size %d.\n",
- message_header->source_vm_id,
- message_header->length);
+ spci_msg_send_sender(ret),
+ spci_msg_send_size(ret));
}
message = message_header->payload;
@@ -113,9 +113,10 @@
event_wait();
}
} else if (receive) {
- int32_t res = spci_msg_wait();
+ struct spci_value res = spci_msg_wait();
- EXPECT_EQ(res, SPCI_INTERRUPTED);
+ EXPECT_EQ(res.func, SPCI_ERROR_32);
+ EXPECT_EQ(res.arg1, SPCI_INTERRUPTED);
} else {
/* Busy wait until the timer fires. */
while (!timer_fired) {
diff --git a/test/vmapi/primary_with_secondaries/no_services.c b/test/vmapi/primary_with_secondaries/no_services.c
index 40da63d..0f60bed 100644
--- a/test/vmapi/primary_with_secondaries/no_services.c
+++ b/test/vmapi/primary_with_secondaries/no_services.c
@@ -166,8 +166,8 @@
*/
TEST(hf_mailbox_receive, cannot_receive_from_primary_blocking)
{
- int32_t res = spci_msg_wait();
- EXPECT_NE(res, SPCI_SUCCESS);
+ struct spci_value res = spci_msg_wait();
+ EXPECT_NE(res.func, SPCI_SUCCESS_32);
}
/**
@@ -175,6 +175,6 @@
*/
TEST(hf_mailbox_receive, cannot_receive_from_primary_non_blocking)
{
- int32_t res = spci_msg_poll();
- EXPECT_NE(res, SPCI_SUCCESS);
+ struct spci_value res = spci_msg_poll();
+ EXPECT_NE(res.func, SPCI_SUCCESS_32);
}
diff --git a/test/vmapi/primary_with_secondaries/services/echo.c b/test/vmapi/primary_with_secondaries/services/echo.c
index a9d5b02..87695a8 100644
--- a/test/vmapi/primary_with_secondaries/services/echo.c
+++ b/test/vmapi/primary_with_secondaries/services/echo.c
@@ -25,15 +25,18 @@
{
/* Loop, echo messages back to the sender. */
for (;;) {
- spci_msg_wait();
+ struct spci_value ret = spci_msg_wait();
+ spci_vm_id_t target_vm_id = spci_msg_send_receiver(ret);
+ spci_vm_id_t source_vm_id = spci_msg_send_sender(ret);
struct spci_message *send_buf = SERVICE_SEND_BUFFER();
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
+ ASSERT_EQ(ret.func, SPCI_MSG_SEND_32);
memcpy_s(send_buf->payload, SPCI_MSG_PAYLOAD_MAX,
- recv_buf->payload, recv_buf->length);
- spci_message_init(SERVICE_SEND_BUFFER(), recv_buf->length,
- recv_buf->source_vm_id,
- recv_buf->target_vm_id);
+ recv_buf->payload, spci_msg_send_size(ret));
+ spci_message_init(SERVICE_SEND_BUFFER(),
+ spci_msg_send_size(ret), source_vm_id,
+ target_vm_id);
hf_mailbox_clear();
spci_msg_send(0);
diff --git a/test/vmapi/primary_with_secondaries/services/echo_with_notification.c b/test/vmapi/primary_with_secondaries/services/echo_with_notification.c
index b32a6f6..ffd1e12 100644
--- a/test/vmapi/primary_with_secondaries/services/echo_with_notification.c
+++ b/test/vmapi/primary_with_secondaries/services/echo_with_notification.c
@@ -53,19 +53,19 @@
/* Loop, echo messages back to the sender. */
for (;;) {
- spci_msg_wait();
-
struct spci_message *send_buf = SERVICE_SEND_BUFFER();
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
+ struct spci_value ret = spci_msg_wait();
+ spci_vm_id_t target_vm_id = spci_msg_send_receiver(ret);
+ spci_vm_id_t source_vm_id = spci_msg_send_sender(ret);
memcpy_s(send_buf->payload, SPCI_MSG_PAYLOAD_MAX,
- recv_buf->payload, recv_buf->length);
- spci_message_init(send_buf, recv_buf->length,
- recv_buf->source_vm_id,
- recv_buf->target_vm_id);
+ recv_buf->payload, spci_msg_send_size(ret));
+ spci_message_init(send_buf, spci_msg_send_size(ret),
+ source_vm_id, target_vm_id);
while (spci_msg_send(SPCI_MSG_SEND_NOTIFY) != SPCI_SUCCESS) {
- wait_for_vm(recv_buf->source_vm_id);
+ wait_for_vm(source_vm_id);
}
hf_mailbox_clear();
diff --git a/test/vmapi/primary_with_secondaries/services/interruptible.c b/test/vmapi/primary_with_secondaries/services/interruptible.c
index adc9b16..94ac007 100644
--- a/test/vmapi/primary_with_secondaries/services/interruptible.c
+++ b/test/vmapi/primary_with_secondaries/services/interruptible.c
@@ -51,13 +51,14 @@
* Try to receive a message from the mailbox, blocking if necessary, and
* retrying if interrupted.
*/
-int32_t mailbox_receive_retry()
+struct spci_value mailbox_receive_retry()
{
- int32_t received;
+ struct spci_value received;
do {
received = spci_msg_wait();
- } while (received == SPCI_INTERRUPTED);
+ } while (received.func == SPCI_ERROR_32 &&
+ received.arg1 == SPCI_INTERRUPTED);
return received;
}
@@ -77,22 +78,25 @@
const char ping_message[] = "Ping";
const char enable_message[] = "Enable interrupt C";
- mailbox_receive_retry();
- if (recv_buf->source_vm_id == HF_PRIMARY_VM_ID &&
- recv_buf->length == sizeof(ping_message) &&
+ struct spci_value ret = mailbox_receive_retry();
+
+ ASSERT_EQ(ret.func, SPCI_MSG_SEND_32);
+ if (spci_msg_send_sender(ret) == HF_PRIMARY_VM_ID &&
+ spci_msg_send_size(ret) == sizeof(ping_message) &&
memcmp(recv_buf->payload, ping_message,
sizeof(ping_message)) == 0) {
/* Interrupt ourselves */
hf_interrupt_inject(this_vm_id, 0, SELF_INTERRUPT_ID);
- } else if (recv_buf->source_vm_id == HF_PRIMARY_VM_ID &&
- recv_buf->length == sizeof(enable_message) &&
+ } else if (spci_msg_send_sender(ret) == HF_PRIMARY_VM_ID &&
+ spci_msg_send_size(ret) == sizeof(enable_message) &&
memcmp(recv_buf->payload, enable_message,
sizeof(enable_message)) == 0) {
/* Enable interrupt ID C. */
hf_interrupt_enable(EXTERNAL_INTERRUPT_ID_C, true);
} else {
dlog("Got unexpected message from VM %d, size %d.\n",
- recv_buf->source_vm_id, recv_buf->length);
+ spci_msg_send_sender(ret),
+ spci_msg_send_size(ret));
FAIL("Unexpected message");
}
hf_mailbox_clear();
diff --git a/test/vmapi/primary_with_secondaries/services/interruptible_echo.c b/test/vmapi/primary_with_secondaries/services/interruptible_echo.c
index 07a4cbc..560c47e 100644
--- a/test/vmapi/primary_with_secondaries/services/interruptible_echo.c
+++ b/test/vmapi/primary_with_secondaries/services/interruptible_echo.c
@@ -38,19 +38,21 @@
arch_irq_enable();
for (;;) {
- uint32_t res = spci_msg_wait();
+ struct spci_value res = spci_msg_wait();
struct spci_message *message = SERVICE_SEND_BUFFER();
struct spci_message *recv_message = SERVICE_RECV_BUFFER();
/* Retry if interrupted but made visible with the yield. */
- while (res == SPCI_INTERRUPTED) {
+ while (res.func == SPCI_ERROR_32 &&
+ res.arg1 == SPCI_INTERRUPTED) {
spci_yield();
res = spci_msg_wait();
}
+ ASSERT_EQ(res.func, SPCI_MSG_SEND_32);
memcpy_s(message->payload, SPCI_MSG_PAYLOAD_MAX,
- recv_message->payload, recv_message->length);
- spci_message_init(message, recv_message->length,
+ recv_message->payload, spci_msg_send_size(res));
+ spci_message_init(message, spci_msg_send_size(res),
HF_PRIMARY_VM_ID, SERVICE_VM0);
hf_mailbox_clear();
diff --git a/test/vmapi/primary_with_secondaries/services/memory.c b/test/vmapi/primary_with_secondaries/services/memory.c
index 8e4dc6f..bd12409 100644
--- a/test/vmapi/primary_with_secondaries/services/memory.c
+++ b/test/vmapi/primary_with_secondaries/services/memory.c
@@ -28,15 +28,17 @@
{
/* Loop, writing message to the shared memory. */
for (;;) {
- EXPECT_EQ(spci_msg_wait(), 0);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
size_t i;
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
+
/* Check the memory was cleared. */
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
ptr = *(uint8_t **)recv_buf->payload;
spci_message_init(SERVICE_SEND_BUFFER(), sizeof(ptr),
- recv_buf->source_vm_id, hf_vm_get_id());
+ spci_msg_send_sender(ret), hf_vm_get_id());
for (int i = 0; i < PAGE_SIZE; ++i) {
ASSERT_EQ(ptr[i], 0);
@@ -60,9 +62,11 @@
{
/* Loop, giving memory back to the sender. */
for (;;) {
- spci_msg_wait();
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
+
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_message *send_buf = SERVICE_SEND_BUFFER();
struct spci_memory_region *memory_region =
@@ -82,7 +86,7 @@
hf_mailbox_clear();
/* Give the memory back and notify the sender. */
spci_memory_relinquish(
- send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+ send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
memory_region->constituents, memory_region->count, 0);
spci_msg_send(0);
@@ -98,21 +102,23 @@
{
/* Loop, giving memory back to the sender. */
for (;;) {
- EXPECT_EQ(spci_msg_wait(), 0);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
+
/* Check the memory was cleared. */
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
ptr = *(uint8_t **)recv_buf->payload;
spci_message_init(SERVICE_SEND_BUFFER(), sizeof(ptr),
- recv_buf->source_vm_id, hf_vm_get_id());
+ spci_msg_send_sender(ret), hf_vm_get_id());
for (int i = 0; i < PAGE_SIZE; ++i) {
ASSERT_EQ(ptr[i], 0);
}
/* Give the memory back and notify the sender. */
- ASSERT_EQ(hf_share_memory(recv_buf->source_vm_id,
+ ASSERT_EQ(hf_share_memory(spci_msg_send_sender(ret),
(hf_ipaddr_t)ptr, PAGE_SIZE,
HF_MEMORY_GIVE),
0);
@@ -179,13 +185,14 @@
{
/* Loop, giving memory back to the sender. */
for (;;) {
- EXPECT_EQ(spci_msg_wait(), 0);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
-
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_message *send_buf = SERVICE_SEND_BUFFER();
struct spci_memory_region *memory_region =
spci_get_donated_memory_region(recv_buf);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -197,7 +204,7 @@
/* Give the memory back and notify the sender. */
spci_memory_donate(
- send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+ send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
memory_region->constituents, memory_region->count, 0);
spci_msg_send(0);
@@ -211,12 +218,13 @@
TEST_SERVICE(spci_donate_check_upper_bound)
{
- EXPECT_EQ(spci_msg_wait(), 0);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
-
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_memory_region *memory_region =
spci_get_donated_memory_region(recv_buf);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -227,12 +235,13 @@
TEST_SERVICE(spci_donate_check_lower_bound)
{
- EXPECT_EQ(spci_msg_wait(), 0);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
-
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_memory_region *memory_region =
spci_get_donated_memory_region(recv_buf);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -246,19 +255,20 @@
*/
TEST_SERVICE(spci_donate_secondary_and_fault)
{
- EXPECT_EQ(spci_msg_wait(), 0);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
-
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_message *send_buf = SERVICE_SEND_BUFFER();
struct spci_memory_region *memory_region =
spci_get_donated_memory_region(recv_buf);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
ptr = (uint8_t *)memory_region->constituents[0].address;
/* Donate memory to next VM. */
- spci_memory_donate(send_buf, SERVICE_VM1, recv_buf->target_vm_id,
+ spci_memory_donate(send_buf, SERVICE_VM1, spci_msg_send_receiver(ret),
memory_region->constituents, memory_region->count,
0);
EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
@@ -274,14 +284,15 @@
*/
TEST_SERVICE(spci_donate_twice)
{
- EXPECT_EQ(spci_msg_wait(), 0);
-
+ struct spci_value ret = spci_msg_wait();
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_message *send_buf = SERVICE_SEND_BUFFER();
struct spci_memory_region *memory_region =
spci_get_donated_memory_region(recv_buf);
struct spci_memory_region_constituent constituent =
memory_region->constituents[0];
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
/* Yield to allow attempt to re donate from primary. */
@@ -293,7 +304,7 @@
EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
/* Attempt to donate the memory to another VM. */
- spci_memory_donate(send_buf, SERVICE_VM1, recv_buf->target_vm_id,
+ spci_memory_donate(send_buf, SERVICE_VM1, spci_msg_send_receiver(ret),
&constituent, memory_region->count, 0);
EXPECT_EQ(spci_msg_send(0), SPCI_INVALID_PARAMETERS);
@@ -307,12 +318,13 @@
TEST_SERVICE(spci_memory_receive)
{
for (;;) {
- EXPECT_EQ(spci_msg_wait(), 0);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
-
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_memory_region *memory_region =
spci_get_donated_memory_region(recv_buf);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -330,18 +342,19 @@
*/
TEST_SERVICE(spci_donate_invalid_source)
{
- EXPECT_EQ(spci_msg_wait(), 0);
-
+ struct spci_value ret = spci_msg_wait();
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_message *send_buf = SERVICE_SEND_BUFFER();
struct spci_memory_region *memory_region =
spci_get_donated_memory_region(recv_buf);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
/* Give the memory back and notify the sender. */
- spci_memory_donate(send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
- memory_region->constituents, memory_region->count,
- 0);
+ spci_memory_donate(
+ send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
+ memory_region->constituents, memory_region->count, 0);
EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
/* Fail to donate the memory from the primary to VM1. */
@@ -356,7 +369,7 @@
{
/* Loop, giving memory back to the sender. */
for (;;) {
- EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
@@ -366,6 +379,7 @@
recv_buf)
->payload);
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
ptr = (uint8_t *)memory_region->constituents[0].address;
/* Relevant information read, mailbox can be cleared. */
hf_mailbox_clear();
@@ -378,7 +392,7 @@
hf_mailbox_clear();
/* Give the memory back and notify the sender. */
spci_memory_relinquish(
- send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+ send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
memory_region->constituents, memory_region->count, 0);
spci_msg_send(0);
@@ -396,13 +410,15 @@
TEST_SERVICE(spci_memory_donate_relinquish)
{
for (;;) {
- EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_message *send_buf = SERVICE_SEND_BUFFER();
struct spci_memory_region *memory_region =
spci_get_donated_memory_region(recv_buf);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -413,7 +429,7 @@
}
/* Give the memory back and notify the sender. */
spci_memory_relinquish(
- send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+ send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
memory_region->constituents, memory_region->count, 0);
EXPECT_EQ(spci_msg_send(0), SPCI_INVALID_PARAMETERS);
@@ -429,24 +445,26 @@
*/
TEST_SERVICE(spci_lend_invalid_source)
{
- EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+ struct spci_value ret = spci_msg_wait();
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_message *send_buf = SERVICE_SEND_BUFFER();
struct spci_memory_region *memory_region =
(struct spci_memory_region *)(spci_get_lend_descriptor(recv_buf)
->payload);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
/* Attempt to relinquish from primary VM. */
- spci_memory_relinquish(send_buf, recv_buf->target_vm_id,
+ spci_memory_relinquish(send_buf, spci_msg_send_receiver(ret),
HF_PRIMARY_VM_ID, memory_region->constituents,
memory_region->count, 0);
EXPECT_EQ(spci_msg_send(0), SPCI_INVALID_PARAMETERS);
/* Give the memory back and notify the sender. */
spci_memory_relinquish(
- send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+ send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
memory_region->constituents, memory_region->count, 0);
EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
@@ -465,7 +483,7 @@
TEST_SERVICE(spci_memory_lend_relinquish_X)
{
for (;;) {
- EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+ struct spci_value ret = spci_msg_wait();
uint64_t *ptr;
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
@@ -474,6 +492,8 @@
(struct spci_memory_region *)(spci_get_lend_descriptor(
recv_buf)
->payload);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
ptr = (uint64_t *)memory_region->constituents[0].address;
@@ -487,7 +507,7 @@
/* Release the memory again. */
spci_memory_relinquish(
- send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+ send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
memory_region->constituents, memory_region->count, 0);
EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
}
@@ -499,7 +519,7 @@
TEST_SERVICE(spci_memory_lend_relinquish_RW)
{
for (;;) {
- EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
@@ -508,6 +528,8 @@
(struct spci_memory_region *)(spci_get_lend_descriptor(
recv_buf)
->payload);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -526,7 +548,7 @@
}
spci_memory_relinquish(
- send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+ send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
memory_region->constituents, memory_region->count, 0);
EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
}
@@ -537,13 +559,15 @@
*/
TEST_SERVICE(spci_lend_check_lower_bound)
{
- EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_memory_region *memory_region =
(struct spci_memory_region *)(spci_get_lend_descriptor(recv_buf)
->payload);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -557,13 +581,15 @@
*/
TEST_SERVICE(spci_lend_check_upper_bound)
{
- EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_memory_region *memory_region =
(struct spci_memory_region *)(spci_get_lend_descriptor(recv_buf)
->payload);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -574,7 +600,7 @@
TEST_SERVICE(spci_memory_lend_twice)
{
- EXPECT_EQ(spci_msg_wait(), SPCI_SUCCESS);
+ struct spci_value ret = spci_msg_wait();
uint8_t *ptr;
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
@@ -582,6 +608,8 @@
struct spci_memory_region *memory_region =
(struct spci_memory_region *)(spci_get_lend_descriptor(recv_buf)
->payload);
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
hf_mailbox_clear();
ptr = (uint8_t *)memory_region->constituents[0].address;
@@ -612,7 +640,7 @@
}
spci_memory_relinquish(
- send_buf, HF_PRIMARY_VM_ID, recv_buf->target_vm_id,
+ send_buf, HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
memory_region->constituents, memory_region->count, 0);
EXPECT_EQ(spci_msg_send(0), SPCI_SUCCESS);
}
diff --git a/test/vmapi/primary_with_secondaries/services/receive_block.c b/test/vmapi/primary_with_secondaries/services/receive_block.c
index 1b03506..666754f 100644
--- a/test/vmapi/primary_with_secondaries/services/receive_block.c
+++ b/test/vmapi/primary_with_secondaries/services/receive_block.c
@@ -46,8 +46,9 @@
hf_interrupt_enable(EXTERNAL_INTERRUPT_ID_A, true);
for (i = 0; i < 10; ++i) {
- int32_t res = spci_msg_wait();
- EXPECT_EQ(res, SPCI_INTERRUPTED);
+ struct spci_value res = spci_msg_wait();
+ EXPECT_EQ(res.func, SPCI_ERROR_32);
+ EXPECT_EQ(res.arg1, SPCI_INTERRUPTED);
}
memcpy_s(SERVICE_SEND_BUFFER()->payload, SPCI_MSG_PAYLOAD_MAX, message,
diff --git a/test/vmapi/primary_with_secondaries/services/relay.c b/test/vmapi/primary_with_secondaries/services/relay.c
index 86eed79..1003699 100644
--- a/test/vmapi/primary_with_secondaries/services/relay.c
+++ b/test/vmapi/primary_with_secondaries/services/relay.c
@@ -36,17 +36,19 @@
uint32_t next_message_size;
/* Receive the message to relay. */
- spci_msg_wait();
+ struct spci_value ret = spci_msg_wait();
+ ASSERT_EQ(ret.func, SPCI_MSG_SEND_32);
/* Prepare to relay the message. */
struct spci_message *recv_buf = SERVICE_RECV_BUFFER();
struct spci_message *send_buf = SERVICE_SEND_BUFFER();
- ASSERT_GE(recv_buf->length, sizeof(spci_vm_id_t));
+ ASSERT_GE(spci_msg_send_size(ret), sizeof(spci_vm_id_t));
chain = (spci_vm_id_t *)recv_buf->payload;
next_vm_id = le16toh(*chain);
next_message = chain + 1;
- next_message_size = recv_buf->length - sizeof(spci_vm_id_t);
+ next_message_size =
+ spci_msg_send_size(ret) - sizeof(spci_vm_id_t);
/* Send the message to the next stage. */
memcpy_s(send_buf->payload, SPCI_MSG_PAYLOAD_MAX, next_message,
diff --git a/test/vmapi/primary_with_secondaries/services/spci_check.c b/test/vmapi/primary_with_secondaries/services/spci_check.c
index 1d626ba..3ce9a1f 100644
--- a/test/vmapi/primary_with_secondaries/services/spci_check.c
+++ b/test/vmapi/primary_with_secondaries/services/spci_check.c
@@ -29,7 +29,7 @@
struct spci_message expected_message = {
.flags = SPCI_MESSAGE_IMPDEF_MASK,
.length = sizeof(message),
- .target_vm_id = SERVICE_VM0,
+ .target_vm_id = hf_vm_get_id(),
.source_vm_id = HF_PRIMARY_VM_ID,
/*
@@ -41,20 +41,14 @@
};
/* Wait for single message to be sent by the primary VM. */
- spci_msg_wait();
+ struct spci_value ret = spci_msg_wait();
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
/* Ensure message header has all fields correctly set. */
- EXPECT_EQ(recv_buf->flags, expected_message.flags);
- EXPECT_EQ(recv_buf->length, expected_message.length);
- EXPECT_EQ(recv_buf->target_vm_id, expected_message.target_vm_id);
- EXPECT_EQ(recv_buf->source_vm_id, expected_message.source_vm_id);
-
- /* TODO: Padding fields may be set to MBZ in the next SPCI spec
- * versions. */
- EXPECT_EQ(recv_buf->reserved_1, expected_message.reserved_1);
- EXPECT_EQ(recv_buf->reserved_2, expected_message.reserved_2);
-
- /* Ensure message header has all fields correctly set. */
+ EXPECT_EQ(spci_msg_send_size(ret), sizeof(message));
+ EXPECT_EQ(spci_msg_send_receiver(ret), hf_vm_get_id());
+ EXPECT_EQ(spci_msg_send_sender(ret), HF_PRIMARY_VM_ID);
EXPECT_EQ(memcmp(recv_buf, &expected_message, sizeof(expected_message)),
0);
@@ -70,14 +64,17 @@
const char message[] = "this should be truncated";
/* Wait for single message to be sent by the primary VM. */
- spci_msg_wait();
+ struct spci_value ret = spci_msg_wait();
+
+ EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
/* Verify the length is as expected. */
- EXPECT_EQ(16, recv_buf->length);
+ EXPECT_EQ(16, spci_msg_send_size(ret));
/* Check only part of the message is sent correctly. */
EXPECT_NE(memcmp(recv_buf->payload, message, sizeof(message)), 0);
- EXPECT_EQ(memcmp(recv_buf->payload, message, recv_buf->length), 0);
+ EXPECT_EQ(memcmp(recv_buf->payload, message, spci_msg_send_size(ret)),
+ 0);
spci_yield();
}
@@ -85,7 +82,10 @@
TEST_SERVICE(spci_recv_non_blocking)
{
/* Wait for single message to be sent by the primary VM. */
- EXPECT_EQ(spci_msg_poll(), SPCI_RETRY);
+ struct spci_value ret = spci_msg_poll();
+
+ EXPECT_EQ(ret.func, SPCI_ERROR_32);
+ EXPECT_EQ(ret.arg1, SPCI_RETRY);
spci_yield();
}