Skip to content

Commit 192e88c

Browse files
committed
firmware: arm_ffa: Implement notification bitmap create and destroy interfaces
On systems without a hypervisor the responsibility of requesting the creation of the notification bitmaps in the SPM falls to the FF-A driver. We use FFA features to determine if the ABI is supported, if it is not we can assume there is a hypervisor present and will take care of ensure the relevant notifications bitmaps are created on this partitions behalf. An endpoint’s notification bitmaps needs to be setup before it configures its notifications and before other endpoints and partition managers can start signaling these notifications. Add interface to create and destroy the notification bitmaps and use the same to do the necessary setup during the initialisation and cleanup during the module exit. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sudeep Holla <[email protected]>
1 parent 1609626 commit 192e88c

File tree

1 file changed

+62
-1
lines changed

1 file changed

+62
-1
lines changed

drivers/firmware/arm_ffa/driver.c

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ struct ffa_drv_info {
8484
void *rx_buffer;
8585
void *tx_buffer;
8686
bool mem_ops_native;
87+
bool bitmap_created;
8788
};
8889

8990
static struct ffa_drv_info *drv_info;
@@ -555,6 +556,37 @@ static int ffa_features(u32 func_feat_id, u32 input_props,
555556
return 0;
556557
}
557558

559+
static int ffa_notification_bitmap_create(void)
560+
{
561+
ffa_value_t ret;
562+
u16 vcpu_count = nr_cpu_ids;
563+
564+
invoke_ffa_fn((ffa_value_t){
565+
.a0 = FFA_NOTIFICATION_BITMAP_CREATE,
566+
.a1 = drv_info->vm_id, .a2 = vcpu_count,
567+
}, &ret);
568+
569+
if (ret.a0 == FFA_ERROR)
570+
return ffa_to_linux_errno((int)ret.a2);
571+
572+
return 0;
573+
}
574+
575+
static int ffa_notification_bitmap_destroy(void)
576+
{
577+
ffa_value_t ret;
578+
579+
invoke_ffa_fn((ffa_value_t){
580+
.a0 = FFA_NOTIFICATION_BITMAP_DESTROY,
581+
.a1 = drv_info->vm_id,
582+
}, &ret);
583+
584+
if (ret.a0 == FFA_ERROR)
585+
return ffa_to_linux_errno((int)ret.a2);
586+
587+
return 0;
588+
}
589+
558590
static void ffa_set_up_mem_ops_native_flag(void)
559591
{
560592
if (!ffa_features(FFA_FN_NATIVE(MEM_LEND), 0, NULL, NULL) ||
@@ -704,6 +736,34 @@ static void ffa_setup_partitions(void)
704736
kfree(pbuf);
705737
}
706738

739+
static int ffa_notifications_setup(void)
740+
{
741+
int ret;
742+
743+
ret = ffa_features(FFA_NOTIFICATION_BITMAP_CREATE, 0, NULL, NULL);
744+
if (ret) {
745+
pr_err("Notifications not supported, continuing with it ..\n");
746+
return 0;
747+
}
748+
749+
ret = ffa_notification_bitmap_create();
750+
if (ret) {
751+
pr_err("notification_bitmap_create error %d\n", ret);
752+
return ret;
753+
}
754+
drv_info->bitmap_created = true;
755+
756+
return 0;
757+
}
758+
759+
static void ffa_notifications_cleanup(void)
760+
{
761+
if (drv_info->bitmap_created) {
762+
ffa_notification_bitmap_destroy();
763+
drv_info->bitmap_created = false;
764+
}
765+
}
766+
707767
static int __init ffa_init(void)
708768
{
709769
int ret;
@@ -759,7 +819,7 @@ static int __init ffa_init(void)
759819

760820
ffa_set_up_mem_ops_native_flag();
761821

762-
return 0;
822+
return ffa_notifications_setup();
763823
free_pages:
764824
if (drv_info->tx_buffer)
765825
free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE);
@@ -774,6 +834,7 @@ subsys_initcall(ffa_init);
774834

775835
static void __exit ffa_exit(void)
776836
{
837+
ffa_notifications_cleanup();
777838
ffa_rxtx_unmap(drv_info->vm_id);
778839
free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE);
779840
free_pages_exact(drv_info->rx_buffer, RXTX_BUFFER_SIZE);

0 commit comments

Comments
 (0)