fix(notifications): counter pending notifications
The counter for the pending notifications in the system
was getting corrupted when setting that had been already
set.
Changes the unit test `vm_notifications_set_and_get` to
recreate state change.
Fixed the function `vm_notifications_state_set` to exclude
from the notifications bitmap, the bits which are already
set pending.
Signed-off-by: J-Alves <joao.alves@arm.com>
Change-Id: I8fa6e4e7190498fb4b389d68906d950a683b1136
diff --git a/src/vm.c b/src/vm.c
index f9506b9..9713960 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -718,8 +718,16 @@
static void vm_notifications_state_set(struct notifications_state *state,
ffa_notifications_bitmap_t notifications)
{
- state->pending |= notifications;
- vm_notifications_pending_count_add(notifications);
+ /*
+ * Exclude notifications which are already pending, to avoid
+ * leaving the pending counter in a wrongful state.
+ */
+ ffa_notifications_bitmap_t to_set =
+ (state->pending & notifications) ^ notifications;
+
+ /* Change the state of the pending notifications. */
+ state->pending |= to_set;
+ vm_notifications_pending_count_add(to_set);
}
void vm_notifications_partition_set_pending(
diff --git a/src/vm_test.cc b/src/vm_test.cc
index 9dc76e1..f1a2d5a 100644
--- a/src/vm_test.cc
+++ b/src/vm_test.cc
@@ -415,6 +415,14 @@
*/
vm_notifications_partition_set_pending(current_vm_locked, is_from_vm,
per_vcpu, vcpu_idx, true);
+
+ /*
+ * Duplicate call to check that the state of the counters doesn't alter
+ * because of it.
+ */
+ vm_notifications_partition_set_pending(current_vm_locked, is_from_vm,
+ per_vcpu, vcpu_idx, true);
+
EXPECT_FALSE(vm_is_notifications_pending_count_zero());
ret = vm_notifications_partition_get_pending(current_vm_locked,