test(notifications): per-vCPU notifications from VM to SP
Change-Id: I86290fe89d718e5740b96d6142db11a5a77bb9f2
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/inc/vmapi/hf/ffa.h b/inc/vmapi/hf/ffa.h
index 6af065a..cfa44f7 100644
--- a/inc/vmapi/hf/ffa.h
+++ b/inc/vmapi/hf/ffa.h
@@ -506,8 +506,12 @@
#define FFA_NOTIFICATION_FLAG_BITMAP_SPM UINT32_C(0x1 << 2)
#define FFA_NOTIFICATION_FLAG_BITMAP_HYP UINT32_C(0x1 << 3)
+/* Flag to configure notification as being per vCPU. */
+#define FFA_NOTIFICATIONS_FLAG_PER_VCPU UINT32_C(0x1 << 0)
+
/** Flag for FFA_NOTIFICATION_SET to delay Schedule Receiver Interrupt */
#define FFA_NOTIFICATIONS_FLAG_DELAY_SRI UINT32_C(0x1 << 1)
+#define FFA_NOTIFICATIONS_FLAGS_VCPU_ID(id) UINT32_C((id & 0xFFFF) << 16)
static inline ffa_vcpu_index_t ffa_notifications_get_vcpu(struct ffa_value args)
{
diff --git a/test/vmapi/ffa_secure_partitions/notifications.c b/test/vmapi/ffa_secure_partitions/notifications.c
index a593fb7..f117f69 100644
--- a/test/vmapi/ffa_secure_partitions/notifications.c
+++ b/test/vmapi/ffa_secure_partitions/notifications.c
@@ -6,8 +6,11 @@
* https://opensource.org/licenses/BSD-3-Clause.
*/
+#include "hf/arch/vm/power_mgmt.h"
+
#include "hf/dlog.h"
#include "hf/ffa.h"
+#include "hf/spinlock.h"
#include "vmapi/hf/call.h"
@@ -15,6 +18,44 @@
#include "test/hftest.h"
#include "test/vmapi/ffa.h"
+struct notif_cpu_entry_args {
+ struct spinlock *lock;
+ ffa_vcpu_index_t vcpu_id;
+};
+
+static void notif_signal_vm_to_sp(ffa_vm_id_t sender, ffa_vm_id_t receiver,
+ ffa_notifications_bitmap_t bitmap,
+ uint32_t flags)
+{
+ struct ffa_value res;
+ ffa_vcpu_index_t vcpu_id = (flags >> 16U) & 0xFFFFU;
+
+ /* Request receiver to bind notifications. */
+ res = sp_notif_bind_cmd_send(sender, receiver, sender,
+ flags & FFA_NOTIFICATION_FLAG_PER_VCPU,
+ bitmap);
+ EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
+ EXPECT_EQ(sp_resp(res), SP_SUCCESS);
+
+ res = ffa_notification_set(sender, receiver, flags, bitmap);
+ EXPECT_EQ(res.func, FFA_SUCCESS_32);
+
+ res = ffa_notification_info_get();
+ EXPECT_EQ(res.func, FFA_SUCCESS_64);
+
+ /* Request to get notifications pending */
+ res = sp_notif_get_cmd_send(sender, receiver, vcpu_id,
+ FFA_NOTIFICATION_FLAG_BITMAP_VM);
+ EXPECT_EQ(sp_resp(res), SP_SUCCESS);
+ EXPECT_EQ(sp_notif_get_from_sp(res), 0);
+ EXPECT_EQ(sp_notif_get_from_vm(res), bitmap);
+
+ /* Request to unbind notifications */
+ res = sp_notif_unbind_cmd_send(sender, receiver, sender, bitmap);
+ EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
+ EXPECT_EQ(sp_resp(res), SP_SUCCESS);
+}
+
/**
* Test to validate notifications signaling from an SP to a VM.
*/
@@ -32,7 +73,6 @@
/* Requesting sender to set notification. */
res = sp_notif_set_cmd_send(own_id, notification_sender, own_id,
FFA_NOTIFICATIONS_FLAG_DELAY_SRI, bitmap);
-
EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
EXPECT_EQ(sp_resp(res), SP_SUCCESS);
@@ -59,35 +99,56 @@
*/
TEST(ffa_notifications, signaling_from_vm_to_sp)
{
- struct ffa_value res;
- ffa_vm_id_t own_id = hf_vm_get_id();
- const ffa_vm_id_t notification_receiver = SP_ID(1);
- const ffa_notifications_bitmap_t bitmap = FFA_NOTIFICATION_MASK(35);
+ notif_signal_vm_to_sp(hf_vm_get_id(), SP_ID(1),
+ FFA_NOTIFICATION_MASK(35),
+ FFA_NOTIFICATIONS_FLAG_DELAY_SRI);
+}
- /* Request receiver to bind notifications. */
- res = sp_notif_bind_cmd_send(own_id, notification_receiver, own_id, 0,
- bitmap);
- EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
- EXPECT_EQ(sp_resp(res), SP_SUCCESS);
+static void cpu_entry_vm_to_sp_signaling(uintptr_t arg)
+{
+ struct notif_cpu_entry_args *test_args =
+ // NOLINTNEXTLINE(performance-no-int-to-ptr)
+ (struct notif_cpu_entry_args *)arg;
- res = ffa_notification_set(own_id, notification_receiver,
- FFA_NOTIFICATIONS_FLAG_DELAY_SRI, bitmap);
- EXPECT_EQ(res.func, FFA_SUCCESS_32);
+ notif_signal_vm_to_sp(
+ hf_vm_get_id(), SP_ID(1),
+ FFA_NOTIFICATION_MASK(test_args->vcpu_id),
+ FFA_NOTIFICATIONS_FLAG_DELAY_SRI |
+ FFA_NOTIFICATIONS_FLAG_PER_VCPU |
+ FFA_NOTIFICATIONS_FLAGS_VCPU_ID(test_args->vcpu_id));
- res = ffa_notification_info_get();
- EXPECT_EQ(res.func, FFA_SUCCESS_64);
+ sl_unlock(test_args->lock);
- /* Request to get notifications pending */
- res = sp_notif_get_cmd_send(own_id, notification_receiver, 0,
- FFA_NOTIFICATION_FLAG_BITMAP_VM);
+ arch_cpu_stop();
+}
- EXPECT_EQ(sp_resp(res), SP_SUCCESS);
- EXPECT_EQ(sp_notif_get_from_sp(res), 0);
- EXPECT_EQ(sp_notif_get_from_vm(res), bitmap);
+TEST(ffa_notifications, per_vcpu_vm_to_sp)
+{
+ struct spinlock lock = SPINLOCK_INIT;
+ alignas(4096) static uint8_t other_stack[MAX_CPUS - 1][4096];
+ struct notif_cpu_entry_args args = {.lock = &lock};
- /* Request to unbind notifications */
- res = sp_notif_unbind_cmd_send(own_id, notification_receiver, own_id,
- bitmap);
- EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
- EXPECT_EQ(sp_resp(res), SP_SUCCESS);
+ /* Start secondary while holding lock. */
+ sl_lock(&lock);
+
+ for (size_t i = 1; i < MAX_CPUS - 1; i++) {
+ size_t hftest_cpu_index = MAX_CPUS - i;
+ HFTEST_LOG(
+ "Notifications signaling VM to SP. Booting CPU %u. \n",
+ i);
+
+ args.vcpu_id = i;
+
+ EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(hftest_cpu_index),
+ other_stack[i - 1],
+ sizeof(other_stack[0]),
+ cpu_entry_vm_to_sp_signaling,
+ (uintptr_t)&args),
+ true);
+
+ /* Wait for CPU to release the lock. */
+ sl_lock(&lock);
+
+ HFTEST_LOG("Done with CPU %u\n", i);
+ }
}
diff --git a/test/vmapi/ffa_secure_partitions/services/inc/partition_services.h b/test/vmapi/ffa_secure_partitions/services/inc/partition_services.h
index 3a08de5..638ef6c 100644
--- a/test/vmapi/ffa_secure_partitions/services/inc/partition_services.h
+++ b/test/vmapi/ffa_secure_partitions/services/inc/partition_services.h
@@ -130,6 +130,11 @@
vcpu_id, flags, 0, 0);
}
+static inline uint16_t sp_notif_vcpu(struct ffa_value cmd)
+{
+ return (uint16_t)cmd.arg4;
+}
+
struct ffa_value sp_notif_get_cmd(ffa_vm_id_t test_source, uint16_t vcpu_id,
uint32_t flags);
diff --git a/test/vmapi/ffa_secure_partitions/services/message_loop.c b/test/vmapi/ffa_secure_partitions/services/message_loop.c
index 3144a95..5b7723d 100644
--- a/test/vmapi/ffa_secure_partitions/services/message_loop.c
+++ b/test/vmapi/ffa_secure_partitions/services/message_loop.c
@@ -46,7 +46,8 @@
sp_notif_flags(res), sp_notif_bitmap(res));
break;
case SP_NOTIF_GET_CMD:
- res = sp_notif_get_cmd(ffa_sender(res), 0,
+ res = sp_notif_get_cmd(ffa_sender(res),
+ sp_notif_vcpu(res),
sp_notif_flags(res));
break;
case SP_NOTIF_BIND_CMD: