feat(scheduled mode): unwind call chain for FFA_MSG_SEND_DIRECT_RESP
This patch performs the action of unwinding the SP call chain upon
FFA_MSG_SEND_DIRECT_RESP invocation.
Change-Id: I26d1ecae2d4c0d21f8780eff0b99f355ea910914
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
diff --git a/src/api.c b/src/api.c
index ab9aa5b..e61c7a6 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2741,6 +2741,8 @@
panic("Invalid direct message response invocation");
}
+ plat_ffa_unwind_call_chain_ffa_direct_resp(current, *next);
+
return (struct ffa_value){.func = FFA_INTERRUPT_32};
}
diff --git a/src/arch/aarch64/plat/ffa/absent.c b/src/arch/aarch64/plat/ffa/absent.c
index 6825931..be8c458 100644
--- a/src/arch/aarch64/plat/ffa/absent.c
+++ b/src/arch/aarch64/plat/ffa/absent.c
@@ -478,3 +478,10 @@
(void)current_locked;
(void)receiver_vcpu_locked;
}
+
+void plat_ffa_unwind_call_chain_ffa_direct_resp(struct vcpu *current,
+ struct vcpu *next)
+{
+ (void)current;
+ (void)next;
+}
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
index 8ca0321..467a37a 100644
--- a/src/arch/aarch64/plat/ffa/hypervisor.c
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -982,3 +982,11 @@
(void)current_locked;
(void)receiver_vcpu_locked;
}
+
+void plat_ffa_unwind_call_chain_ffa_direct_resp(struct vcpu *current,
+ struct vcpu *next)
+{
+ /* Calls chains not supported in the Hypervisor/VMs. */
+ (void)current;
+ (void)next;
+}
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index c1e46da..dff129d 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -1904,3 +1904,31 @@
receiver_vcpu->scheduling_mode = current->scheduling_mode;
}
}
+
+/*
+ * Unwind the present call chain upon the invocation of
+ * FFA_MSG_SEND_DIRECT_RESP ABI.
+ */
+void plat_ffa_unwind_call_chain_ffa_direct_resp(struct vcpu *current,
+ struct vcpu *next)
+{
+ ffa_vm_id_t receiver_vm_id = next->vm->id;
+
+ /* Lock both vCPUs at once. */
+ vcpu_lock_both(current, next);
+
+ assert(current->call_chain.next_node == NULL);
+ current->scheduling_mode = NONE;
+ current->rt_model = RTM_NONE;
+
+ if (!vm_id_is_current_world(receiver_vm_id)) {
+ /* End of NWd scheduled call chain. */
+ assert(current->call_chain.prev_node == NULL);
+ } else {
+ /* Removing a node from an existing call chain. */
+ vcpu_call_chain_remove_node(current, next);
+ }
+
+ sl_unlock(&next->lock);
+ sl_unlock(¤t->lock);
+}
diff --git a/src/arch/fake/hypervisor/ffa.c b/src/arch/fake/hypervisor/ffa.c
index 3a9e8dd..2983ef3 100644
--- a/src/arch/fake/hypervisor/ffa.c
+++ b/src/arch/fake/hypervisor/ffa.c
@@ -449,3 +449,11 @@
(void)current_locked;
(void)receiver_vcpu_locked;
}
+
+void plat_ffa_unwind_call_chain_ffa_direct_resp(struct vcpu *current,
+ struct vcpu *next)
+{
+ /* Calls chains not supported in the Hypervisor/VMs. */
+ (void)current;
+ (void)next;
+}