fix: make the invocation of ffa_msg_wait v1.1 compliant
The invocation of FFA_MSG_WAIT at secure virtual FF-A instance is
made to be compliant with FF-A v1.1 EAC0 specification. It's
only use is to perform the state transition from RUNNING to WAITING
for the following Partition runtime models: RTM_FFA_RUN,
RTM_SEC_INTERRUPT, and RTM_SP_INIT.
However, the invocation of FFA_MSG_WAIT at non-secure virtual FF-A
instance is made to be compliant with the FF-A v1.0 spec for
legacy reasons.
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Change-Id: Ic63f07c9ce6e6c3be9df2a849900b30eb61fcf6d
diff --git a/src/api.c b/src/api.c
index 568d371..ae9bb68 100644
--- a/src/api.c
+++ b/src/api.c
@@ -692,7 +692,6 @@
struct ffa_value api_ffa_msg_wait(struct vcpu *current, struct vcpu **next,
struct ffa_value *args)
{
- struct ffa_value ret;
enum vcpu_state next_state = VCPU_STATE_WAITING;
if (args->arg1 != 0U || args->arg2 != 0U || args->arg3 != 0U ||
@@ -709,11 +708,7 @@
assert(next_state == VCPU_STATE_WAITING);
- if (plat_ffa_msg_wait_prepare(current, next, &ret)) {
- return ret;
- }
-
- return api_ffa_msg_recv(true, current, next);
+ return plat_ffa_msg_wait_prepare(current, next);
}
/**
diff --git a/src/arch/aarch64/plat/ffa/absent.c b/src/arch/aarch64/plat/ffa/absent.c
index bb8b9e8..43eb9b4 100644
--- a/src/arch/aarch64/plat/ffa/absent.c
+++ b/src/arch/aarch64/plat/ffa/absent.c
@@ -445,14 +445,13 @@
(void)ppool;
}
-bool plat_ffa_msg_wait_prepare(struct vcpu *current, struct vcpu **next,
- struct ffa_value *ret_args)
+struct ffa_value plat_ffa_msg_wait_prepare(struct vcpu *current,
+ struct vcpu **next)
{
(void)current;
(void)next;
- (void)ret_args;
- return false;
+ return (struct ffa_value){.func = FFA_INTERRUPT_32};
}
bool plat_ffa_check_runtime_state_transition(struct vcpu *current,
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
index 1668ac1..e7f9e94 100644
--- a/src/arch/aarch64/plat/ffa/hypervisor.c
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -11,6 +11,7 @@
#include "hf/arch/other_world.h"
#include "hf/arch/plat/ffa.h"
+#include "hf/api.h"
#include "hf/dlog.h"
#include "hf/ffa.h"
#include "hf/ffa_internal.h"
@@ -933,14 +934,15 @@
return false;
}
-bool plat_ffa_msg_wait_prepare(struct vcpu *current, struct vcpu **next,
- struct ffa_value *ret_args)
+/**
+ * The invocation of FFA_MSG_WAIT at non-secure virtual FF-A instance is made
+ * to be compliant with version v1.0 of the FF-A specification. It serves as
+ * a blocking call.
+ */
+struct ffa_value plat_ffa_msg_wait_prepare(struct vcpu *current,
+ struct vcpu **next)
{
- (void)current;
- (void)next;
- (void)ret_args;
-
- return false;
+ return api_ffa_msg_recv(true, current, next);
}
bool plat_ffa_check_runtime_state_transition(
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index 4a91e16..4747cf8 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -1937,19 +1937,29 @@
return ret;
}
-bool plat_ffa_msg_wait_prepare(struct vcpu *current, struct vcpu **next,
- struct ffa_value *ret_args)
+/**
+ * The invocation of FFA_MSG_WAIT at secure virtual FF-A instance is compliant
+ * with FF-A v1.1 EAC0 specification. It only performs the state transition
+ * from RUNNING to WAITING for the following Partition runtime models:
+ * RTM_FFA_RUN, RTM_SEC_INTERRUPT, RTM_SP_INIT.
+ */
+struct ffa_value plat_ffa_msg_wait_prepare(struct vcpu *current,
+ struct vcpu **next)
{
+ struct ffa_value ret_args =
+ (struct ffa_value){.func = FFA_INTERRUPT_32};
bool boot_order_complete = false;
if (sp_boot_next(current, next, &boot_order_complete)) {
- *ret_args = (struct ffa_value){.func = FFA_INTERRUPT_32};
- return true;
+ return ret_args;
}
/* All the SPs have been booted now. Return to NWd. */
if (boot_order_complete) {
- return false;
+ *next = api_switch_to_other_world(
+ current, (struct ffa_value){.func = FFA_MSG_WAIT_32},
+ VCPU_STATE_WAITING);
+ return ret_args;
}
/* Refer FF-A v1.1 Beta0 section 7.4 bullet 2. */
@@ -1964,13 +1974,11 @@
/* Secure interrupt pre-empted normal world. */
if (current->preempted_vcpu->vm->id == HF_OTHER_WORLD_ID) {
- *ret_args = plat_ffa_normal_world_resume(current, next);
- return true;
+ return plat_ffa_normal_world_resume(current, next);
}
/* Secure interrupt pre-empted an SP. Resume it. */
- *ret_args = plat_ffa_preempted_vcpu_resume(current, next);
- return true;
+ return plat_ffa_preempted_vcpu_resume(current, next);
}
/*
@@ -1982,7 +1990,12 @@
current->rt_model = RTM_NONE;
sl_unlock(¤t->lock);
- return false;
+ /* Relinquish control back to the NWd. */
+ *next = api_switch_to_other_world(
+ current, (struct ffa_value){.func = FFA_MSG_WAIT_32},
+ VCPU_STATE_WAITING);
+
+ return ret_args;
}
struct vcpu *plat_ffa_unwind_nwd_call_chain_interrupt(struct vcpu *current_vcpu)
diff --git a/src/arch/fake/hypervisor/ffa.c b/src/arch/fake/hypervisor/ffa.c
index 0f45e3b..7515ebb 100644
--- a/src/arch/fake/hypervisor/ffa.c
+++ b/src/arch/fake/hypervisor/ffa.c
@@ -413,14 +413,14 @@
{
return false;
}
-bool plat_ffa_msg_wait_prepare(struct vcpu *current, struct vcpu **next,
- struct ffa_value *ret_args)
+
+struct ffa_value plat_ffa_msg_wait_prepare(struct vcpu *current,
+ struct vcpu **next)
{
(void)current;
(void)next;
- (void)ret_args;
- return false;
+ return (struct ffa_value){.func = FFA_INTERRUPT_32};
}
bool plat_ffa_check_runtime_state_transition(struct vcpu *current,