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,