feat(notifications): info get framework notifications
Include framework in the processing of FFA_NOTIFICATION_INFO_GET:
- Hypervisor only cares about notifications targeting VMs.
- SPMC retrieves information of notifications targeting SPs and VMs.
Change-Id: I6ea4a5cf1c14437e01666426c293e20c2f028110
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index e172e7e..442bc6b 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -653,43 +653,39 @@
uint32_t *lists_count,
const uint32_t ids_count_max)
{
- enum notifications_info_get_state info_get_state = INIT;
struct nwd_vms_locked nwd_vms_locked = nwd_vms_lock();
struct vm_locked other_world_locked = vm_find_locked(HF_OTHER_WORLD_ID);
+ /*
+ * Variable to save return from 'vm_notifications_info_get'. To be
+ * returned and used as indicator that scheduler should conduct more
+ * calls to retrieve info of pending notifications.
+ */
+ bool list_full_and_more_pending = false;
CHECK(other_world_locked.vm != NULL);
- vm_notifications_info_get_pending(other_world_locked, false, ids,
- ids_count, lists_sizes, lists_count,
- ids_count_max, &info_get_state);
+ list_full_and_more_pending = vm_notifications_info_get(
+ other_world_locked, ids, ids_count, lists_sizes, lists_count,
+ ids_count_max);
vm_unlock(&other_world_locked);
- if (info_get_state == FULL) {
- goto out;
- }
-
- for (unsigned int i = 0; i < nwd_vms_size; i++) {
- info_get_state = INIT;
-
+ for (ffa_vm_count_t i = 0;
+ i < nwd_vms_size && !list_full_and_more_pending; i++) {
if (nwd_vms[i].id != HF_INVALID_VM_ID) {
struct vm_locked vm_locked = vm_lock(&nwd_vms[i]);
- vm_notifications_info_get_pending(
- vm_locked, false, ids, ids_count, lists_sizes,
- lists_count, ids_count_max, &info_get_state);
+ list_full_and_more_pending = vm_notifications_info_get(
+ vm_locked, ids, ids_count, lists_sizes,
+ lists_count, ids_count_max);
vm_unlock(&vm_locked);
-
- if (info_get_state == FULL) {
- goto out;
- }
}
}
-out:
+
nwd_vms_unlock(&nwd_vms_locked);
- return info_get_state == FULL;
+ return list_full_and_more_pending;
}
bool plat_ffa_is_mem_perm_get_valid(const struct vcpu *current)
diff --git a/src/vm.c b/src/vm.c
index f5b8bbc..f67bdd6 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -905,12 +905,18 @@
{
enum notifications_info_get_state current_state = INIT;
- /* Get info of pending notifications from SPs */
+ /* Get info of pending notifications from the framework. */
+ vm_notifications_state_info_get(&vm_locked.vm->notifications.framework,
+ vm_locked.vm->id, false, 0, ids,
+ ids_count, lists_sizes, lists_count,
+ ids_max_count, ¤t_state);
+
+ /* Get info of pending notifications from SPs. */
vm_notifications_info_get_pending(vm_locked, false, ids, ids_count,
lists_sizes, lists_count,
ids_max_count, ¤t_state);
- /* Get info of pending notifications from VMs */
+ /* Get info of pending notifications from VMs. */
vm_notifications_info_get_pending(vm_locked, true, ids, ids_count,
lists_sizes, lists_count,
ids_max_count, ¤t_state);
diff --git a/src/vm_test.cc b/src/vm_test.cc
index cffe5e6..e7934f8 100644
--- a/src/vm_test.cc
+++ b/src/vm_test.cc
@@ -688,4 +688,29 @@
vm_unlock(¤t_vm_locked);
}
+TEST_F(vm, vm_notifications_info_get_from_framework)
+{
+ struct vm_locked vm_locked = vm_lock(vm_find_index(0));
+ uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
+ uint32_t ids_count = 0;
+ uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
+ uint32_t lists_count = 0;
+
+ vm_notifications_framework_set_pending(vm_locked, 0x1U);
+
+ /* Get notifications info for the given notifications. */
+ vm_notifications_info_get(vm_locked, ids, &ids_count, lists_sizes,
+ &lists_count,
+ FFA_NOTIFICATIONS_INFO_GET_MAX_IDS);
+
+ EXPECT_EQ(ids[0], vm_locked.vm->id);
+ EXPECT_EQ(ids_count, 1);
+ EXPECT_EQ(lists_sizes[0], 0);
+ EXPECT_EQ(lists_count, 1);
+
+ EXPECT_EQ(vm_notifications_framework_get_pending(vm_locked), 0x1U);
+
+ vm_unlock(&vm_locked);
+}
+
} /* namespace */