feat(notifications): hypervisor forward bind/unbind
Hypervisor forwards call to SPMC of bind/unbind interfaces, when
the specified sender is an SP.
This will be useful for testing notifications with both hypervisor and
SPMC.
Change-Id: I62c44211f251a84d6bdc459bbe6b8d4fb2571933
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/src/api.c b/src/api.c
index 7b615ce..37a6ca9 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2599,6 +2599,13 @@
return ffa_error(FFA_INVALID_PARAMETERS);
}
+ if (plat_ffa_notifications_update_bindings_forward(
+ receiver_vm_id, sender_vm_id, flags, notifications, is_bind,
+ &ret)) {
+ dlog_verbose("Forwarding call to other world.\n");
+ return ret;
+ }
+
if (notifications == 0U) {
dlog_verbose("No notifications have been specified.\n");
return ffa_error(FFA_INVALID_PARAMETERS);
diff --git a/src/arch/aarch64/plat/ffa/absent.c b/src/arch/aarch64/plat/ffa/absent.c
index e9a10e6..6a27d69 100644
--- a/src/arch/aarch64/plat/ffa/absent.c
+++ b/src/arch/aarch64/plat/ffa/absent.c
@@ -111,6 +111,21 @@
return false;
}
+bool plat_ffa_notifications_update_bindings_forward(
+ ffa_vm_id_t receiver_id, ffa_vm_id_t sender_id, uint32_t flags,
+ ffa_notifications_bitmap_t bitmap, bool is_bind, struct ffa_value *ret)
+{
+ (void)ret;
+ (void)receiver_id;
+ (void)sender_id;
+ (void)flags;
+ (void)bitmap;
+ (void)is_bind;
+ (void)ret;
+
+ return false;
+}
+
bool plat_ffa_is_notification_set_valid(struct vcpu *current,
ffa_vm_id_t sender_id,
ffa_vm_id_t receiver_id)
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
index ba9ae23..350763b 100644
--- a/src/arch/aarch64/plat/ffa/hypervisor.c
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -240,6 +240,27 @@
return sender_id != receiver_id && current_vm_id == receiver_id;
}
+bool plat_ffa_notifications_update_bindings_forward(
+ ffa_vm_id_t receiver_id, ffa_vm_id_t sender_id, uint32_t flags,
+ ffa_notifications_bitmap_t bitmap, bool is_bind, struct ffa_value *ret)
+{
+ CHECK(ret != NULL);
+
+ if (vm_id_is_current_world(receiver_id) &&
+ !vm_id_is_current_world(sender_id)) {
+ *ret = arch_other_world_call((struct ffa_value){
+ .func = is_bind ? FFA_NOTIFICATION_BIND_32
+ : FFA_NOTIFICATION_UNBIND_32,
+ .arg1 = (sender_id << 16) | (receiver_id),
+ .arg2 = is_bind ? flags : 0U,
+ .arg3 = (uint32_t)(bitmap),
+ .arg4 = (uint32_t)(bitmap >> 32),
+ });
+ return true;
+ }
+ return false;
+}
+
bool plat_ffa_is_notification_set_valid(struct vcpu *current,
ffa_vm_id_t sender_id,
ffa_vm_id_t receiver_id)
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index d2eb754..817600c 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -197,6 +197,21 @@
vm_id_is_current_world(sender_id)));
}
+bool plat_ffa_notifications_update_bindings_forward(
+ ffa_vm_id_t receiver_id, ffa_vm_id_t sender_id, uint32_t flags,
+ ffa_notifications_bitmap_t bitmap, bool is_bind, struct ffa_value *ret)
+{
+ (void)ret;
+ (void)receiver_id;
+ (void)sender_id;
+ (void)flags;
+ (void)bitmap;
+ (void)is_bind;
+ (void)ret;
+
+ return false;
+}
+
bool plat_ffa_is_notification_set_valid(struct vcpu *current,
ffa_vm_id_t sender_id,
ffa_vm_id_t receiver_id)
diff --git a/src/arch/fake/hypervisor/ffa.c b/src/arch/fake/hypervisor/ffa.c
index 6ea1dda..4dd3fcd 100644
--- a/src/arch/fake/hypervisor/ffa.c
+++ b/src/arch/fake/hypervisor/ffa.c
@@ -91,6 +91,21 @@
return false;
}
+bool plat_ffa_notifications_update_bindings_forward(
+ ffa_vm_id_t receiver_id, ffa_vm_id_t sender_id, uint32_t flags,
+ ffa_notifications_bitmap_t bitmap, bool is_bind, struct ffa_value *ret)
+{
+ (void)ret;
+ (void)receiver_id;
+ (void)sender_id;
+ (void)flags;
+ (void)bitmap;
+ (void)is_bind;
+ (void)ret;
+
+ return false;
+}
+
ffa_partition_properties_t plat_ffa_partition_properties(
ffa_vm_id_t current_id, const struct vm *target)
{