[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240307092132.943881-1-jens.wiklander@linaro.org>
Date: Thu, 7 Mar 2024 10:21:32 +0100
From: Jens Wiklander <jens.wiklander@...aro.org>
To: linux-kernel@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org,
Sudeep Holla <sudeep.holla@....com>
Cc: Marc Bonnici <marc.bonnici@....com>,
Olivier Deprez <Olivier.Deprez@....com>,
Lorenzo Pieralisi <lpieralisi@...nel.org>,
Jens Wiklander <jens.wiklander@...aro.org>
Subject: [PATCH] firmware: arm_ffa: support running as a guest in a vm
Add support for running the driver in a guest to a hypervisor. The main
difference is that the notification interrupt is retrieved
with FFA_FEAT_NOTIFICATION_PENDING_INT and that
FFA_NOTIFICATION_BITMAP_CREATE doesn't need to be called.
FFA_FEAT_NOTIFICATION_PENDING_INT gives the interrupt the hypervisor has
chosen to notify its guest of pending notifications.
Signed-off-by: Jens Wiklander <jens.wiklander@...aro.org>
---
drivers/firmware/arm_ffa/driver.c | 45 ++++++++++++++++++-------------
1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index f2556a8e9401..c183c7d39c0f 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -1306,17 +1306,28 @@ static void ffa_sched_recv_irq_work_fn(struct work_struct *work)
ffa_notification_info_get();
}
+static int ffa_get_notif_intid(int *intid)
+{
+ int ret;
+
+ ret = ffa_features(FFA_FEAT_SCHEDULE_RECEIVER_INT, 0, intid, NULL);
+ if (!ret)
+ return 0;
+ ret = ffa_features(FFA_FEAT_NOTIFICATION_PENDING_INT, 0, intid, NULL);
+ if (!ret)
+ return 0;
+
+ pr_err("Failed to retrieve one of scheduler Rx or notif pending interrupts\n");
+ return ret;
+}
+
static int ffa_sched_recv_irq_map(void)
{
- int ret, irq, sr_intid;
+ int ret, irq, intid;
- /* The returned sr_intid is assumed to be SGI donated to NS world */
- ret = ffa_features(FFA_FEAT_SCHEDULE_RECEIVER_INT, 0, &sr_intid, NULL);
- if (ret < 0) {
- if (ret != -EOPNOTSUPP)
- pr_err("Failed to retrieve scheduler Rx interrupt\n");
+ ret = ffa_get_notif_intid(&intid);
+ if (ret)
return ret;
- }
if (acpi_disabled) {
struct of_phandle_args oirq = {};
@@ -1329,12 +1340,12 @@ static int ffa_sched_recv_irq_map(void)
oirq.np = gic;
oirq.args_count = 1;
- oirq.args[0] = sr_intid;
+ oirq.args[0] = intid;
irq = irq_create_of_mapping(&oirq);
of_node_put(gic);
#ifdef CONFIG_ACPI
} else {
- irq = acpi_register_gsi(NULL, sr_intid, ACPI_EDGE_SENSITIVE,
+ irq = acpi_register_gsi(NULL, intid, ACPI_EDGE_SENSITIVE,
ACPI_ACTIVE_HIGH);
#endif
}
@@ -1442,17 +1453,15 @@ static void ffa_notifications_setup(void)
int ret, irq;
ret = ffa_features(FFA_NOTIFICATION_BITMAP_CREATE, 0, NULL, NULL);
- if (ret) {
- pr_info("Notifications not supported, continuing with it ..\n");
- return;
- }
+ if (!ret) {
- ret = ffa_notification_bitmap_create();
- if (ret) {
- pr_info("Notification bitmap create error %d\n", ret);
- return;
+ ret = ffa_notification_bitmap_create();
+ if (ret) {
+ pr_err("notification_bitmap_create error %d\n", ret);
+ return;
+ }
+ drv_info->bitmap_created = true;
}
- drv_info->bitmap_created = true;
irq = ffa_sched_recv_irq_map();
if (irq <= 0) {
--
2.34.1
Powered by blists - more mailing lists