* [PATCH v3 01/19] firmware: arm_ffa: Replace SCMI by FF-A in the macro
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 02/19] firmware: arm_ffa: Replace UUID buffer to standard UUID format Sudeep Holla
` (18 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Commit 22779149e93d ("firmware: arm_ffa: Emit modalias for FF-A devices")
added modalias for FF-A devices. However the macro added used SCMI
incorrectly. Replace the reference to SCMI by FF-A and update the macro.
(i.e. s/SCMI/FFA/)
No functional change.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/bus.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c
index dfda5ffc14db7208e8b622cdd648194c9cb1ef34..52b1f09209a0e51e321cd23a69aa7e4c4daa8dd1 100644
--- a/drivers/firmware/arm_ffa/bus.c
+++ b/drivers/firmware/arm_ffa/bus.c
@@ -15,7 +15,7 @@
#include "common.h"
-#define SCMI_UEVENT_MODALIAS_FMT "arm_ffa:%04x:%pUb"
+#define FFA_UEVENT_MODALIAS_FMT "arm_ffa:%04x:%pUb"
static DEFINE_IDA(ffa_bus_id);
@@ -68,7 +68,7 @@ static int ffa_device_uevent(const struct device *dev, struct kobj_uevent_env *e
{
const struct ffa_device *ffa_dev = to_ffa_dev(dev);
- return add_uevent_var(env, "MODALIAS=" SCMI_UEVENT_MODALIAS_FMT,
+ return add_uevent_var(env, "MODALIAS=" FFA_UEVENT_MODALIAS_FMT,
ffa_dev->vm_id, &ffa_dev->uuid);
}
@@ -77,7 +77,7 @@ static ssize_t modalias_show(struct device *dev,
{
struct ffa_device *ffa_dev = to_ffa_dev(dev);
- return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT, ffa_dev->vm_id,
+ return sysfs_emit(buf, FFA_UEVENT_MODALIAS_FMT, ffa_dev->vm_id,
&ffa_dev->uuid);
}
static DEVICE_ATTR_RO(modalias);
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 02/19] firmware: arm_ffa: Replace UUID buffer to standard UUID format
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 01/19] firmware: arm_ffa: Replace SCMI by FF-A in the macro Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 03/19] firmware: arm_ffa: Align sync_send_receive{,2} function prototypes Sudeep Holla
` (17 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Currently ffa_partition_info structure holds the UUID in the format
compatible with the firmware interface. However, most of the functions
in the FF-A core driver deals directly with uuid_t type.
Replace UUID buffer to standard UUID format in the ffa_partition_info
structure.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/bus.c | 4 +---
include/linux/arm_ffa.h | 2 +-
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c
index 52b1f09209a0e51e321cd23a69aa7e4c4daa8dd1..a90e2faa990219574ff20b8f573dbb7ca76137d9 100644
--- a/drivers/firmware/arm_ffa/bus.c
+++ b/drivers/firmware/arm_ffa/bus.c
@@ -192,7 +192,6 @@ ffa_device_register(const struct ffa_partition_info *part_info,
const struct ffa_ops *ops)
{
int id, ret;
- uuid_t uuid;
struct device *dev;
struct ffa_device *ffa_dev;
@@ -218,8 +217,7 @@ ffa_device_register(const struct ffa_partition_info *part_info,
ffa_dev->vm_id = part_info->id;
ffa_dev->properties = part_info->properties;
ffa_dev->ops = ops;
- import_uuid(&uuid, (u8 *)part_info->uuid);
- uuid_copy(&ffa_dev->uuid, &uuid);
+ uuid_copy(&ffa_dev->uuid, &part_info->uuid);
ret = device_register(&ffa_dev->dev);
if (ret) {
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index 74169dd0f65948b05991732358855cdc31b54adb..abd0208f0f74c15ef4ee4c81de81eb7800a0eb1d 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -238,7 +238,7 @@ struct ffa_partition_info {
/* partition runs in the AArch64 execution state. */
#define FFA_PARTITION_AARCH64_EXEC BIT(8)
u32 properties;
- u32 uuid[4];
+ uuid_t uuid;
};
static inline
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 03/19] firmware: arm_ffa: Align sync_send_receive{,2} function prototypes
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 01/19] firmware: arm_ffa: Replace SCMI by FF-A in the macro Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 02/19] firmware: arm_ffa: Replace UUID buffer to standard UUID format Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 04/19] firmware: arm_ffa: Fix big-endian support in __ffa_partition_info_get() Sudeep Holla
` (16 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Currently ffa_sync_send_receive2() takes UUID as a separate parameter
instead of using the one available in ffa_device structure.
Change the prototype of ffa_sync_send_receive2() to align with the
ffa_sync_send_receive() and use ffa_device->uuid.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 4 ++--
include/linux/arm_ffa.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 2c2ec3c35f15612168cdf0ef94022e00c08677b5..037e0d684994fd30971f40bf139367d1e45c1bf0 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -1018,14 +1018,14 @@ static int ffa_indirect_msg_send(struct ffa_device *dev, void *buf, size_t sz)
return ffa_msg_send2(drv_info->vm_id, dev->vm_id, buf, sz);
}
-static int ffa_sync_send_receive2(struct ffa_device *dev, const uuid_t *uuid,
+static int ffa_sync_send_receive2(struct ffa_device *dev,
struct ffa_send_direct_data2 *data)
{
if (!drv_info->msg_direct_req2_supp)
return -EOPNOTSUPP;
return ffa_msg_send_direct_req2(drv_info->vm_id, dev->vm_id,
- uuid, data);
+ &dev->uuid, data);
}
static int ffa_memory_share(struct ffa_mem_ops_args *args)
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index abd0208f0f74c15ef4ee4c81de81eb7800a0eb1d..e8b8ae8b192ab11d5550c16fd33fa9d192b07f67 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -439,7 +439,7 @@ struct ffa_msg_ops {
int (*sync_send_receive)(struct ffa_device *dev,
struct ffa_send_direct_data *data);
int (*indirect_send)(struct ffa_device *dev, void *buf, size_t sz);
- int (*sync_send_receive2)(struct ffa_device *dev, const uuid_t *uuid,
+ int (*sync_send_receive2)(struct ffa_device *dev,
struct ffa_send_direct_data2 *data);
};
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 04/19] firmware: arm_ffa: Fix big-endian support in __ffa_partition_info_get()
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (2 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 03/19] firmware: arm_ffa: Align sync_send_receive{,2} function prototypes Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 05/19] firmware: arm_ffa: Fix big-endian support in __ffa_partition_info_regs_get() Sudeep Holla
` (15 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Currently the FF-A driver doesn't support big-endian correctly. It is
hard to regularly test the setup due to lack of test infrastructure and
tools.
In order to support full stack, we need to take small steps in getting
the support for big-endian kernel added slowly. This change fixes the
support in __ffa_partition_info_get() so that the response from the
firmware are converted correctly as required. With this change, we can
enumerate all the FF-A devices correctly in the big-endian kernel.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 037e0d684994fd30971f40bf139367d1e45c1bf0..bc6ffd25ad2e2fea0fe3610cf896718dbed8f0ad 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -276,9 +276,21 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
}
if (buffer && count <= num_partitions)
- for (idx = 0; idx < count; idx++)
- memcpy(buffer + idx, drv_info->rx_buffer + idx * sz,
- buf_sz);
+ for (idx = 0; idx < count; idx++) {
+ struct ffa_partition_info_le {
+ __le16 id;
+ __le16 exec_ctxt;
+ __le32 properties;
+ uuid_t uuid;
+ } *rx_buf = drv_info->rx_buffer + idx * sz;
+ struct ffa_partition_info *buf = buffer + idx;
+
+ buf->id = le16_to_cpu(rx_buf->id);
+ buf->exec_ctxt = le16_to_cpu(rx_buf->exec_ctxt);
+ buf->properties = le32_to_cpu(rx_buf->properties);
+ if (buf_sz > 8)
+ import_uuid(&buf->uuid, (u8 *)&rx_buf->uuid);
+ }
ffa_rx_release();
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 05/19] firmware: arm_ffa: Fix big-endian support in __ffa_partition_info_regs_get()
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (3 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 04/19] firmware: arm_ffa: Fix big-endian support in __ffa_partition_info_get() Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 06/19] firmware: arm_ffa: Refactor addition of partition information into XArray Sudeep Holla
` (14 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Currently the FF-A driver doesn't support big-endian correctly. It is
hard to regularly test the setup due to lack of test infrastructure and
tools.
In order to support full stack, we need to take small steps in getting
the support for big-endian kernel added slowly. This change fixes the
support in __ffa_partition_info_regs_get() so that the response from the
firmware are converted correctly as required. With this change, we can
enumerate all the FF-A devices correctly in the big-endian kernel if the
FFA_PARTITION_INFO_REGS_GET is supported.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index bc6ffd25ad2e2fea0fe3610cf896718dbed8f0ad..87e106c728b89f3ce7c11219cf7cad9cc166dda2 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -307,14 +307,24 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
#define CURRENT_INDEX(x) ((u16)(FIELD_GET(CURRENT_INDEX_MASK, (x))))
#define UUID_INFO_TAG(x) ((u16)(FIELD_GET(UUID_INFO_TAG_MASK, (x))))
#define PARTITION_INFO_SZ(x) ((u16)(FIELD_GET(PARTITION_INFO_SZ_MASK, (x))))
+#define PART_INFO_ID_MASK GENMASK(15, 0)
+#define PART_INFO_EXEC_CXT_MASK GENMASK(31, 16)
+#define PART_INFO_PROPS_MASK GENMASK(63, 32)
+#define PART_INFO_ID(x) ((u16)(FIELD_GET(PART_INFO_ID_MASK, (x))))
+#define PART_INFO_EXEC_CXT(x) ((u16)(FIELD_GET(PART_INFO_EXEC_CXT_MASK, (x))))
+#define PART_INFO_PROPERTIES(x) ((u32)(FIELD_GET(PART_INFO_PROPS_MASK, (x))))
static int
__ffa_partition_info_get_regs(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
struct ffa_partition_info *buffer, int num_parts)
{
u16 buf_sz, start_idx, cur_idx, count = 0, prev_idx = 0, tag = 0;
+ struct ffa_partition_info *buf = buffer;
ffa_value_t partition_info;
do {
+ __le64 *regs;
+ int idx;
+
start_idx = prev_idx ? prev_idx + 1 : 0;
invoke_ffa_fn((ffa_value_t){
@@ -338,8 +348,25 @@ __ffa_partition_info_get_regs(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
if (buf_sz > sizeof(*buffer))
buf_sz = sizeof(*buffer);
- memcpy(buffer + prev_idx * buf_sz, &partition_info.a3,
- (cur_idx - start_idx + 1) * buf_sz);
+ regs = (void *)&partition_info.a3;
+ for (idx = 0; idx < cur_idx - start_idx + 1; idx++, buf++) {
+ union {
+ uuid_t uuid;
+ u64 regs[2];
+ } uuid_regs = {
+ .regs = {
+ le64_to_cpu(*(regs + 1)),
+ le64_to_cpu(*(regs + 2)),
+ }
+ };
+ u64 val = *(u64 *)regs;
+
+ buf->id = PART_INFO_ID(val);
+ buf->exec_ctxt = PART_INFO_EXEC_CXT(val);
+ buf->properties = PART_INFO_PROPERTIES(val);
+ uuid_copy(&buf->uuid, &uuid_regs.uuid);
+ regs += 3;
+ }
prev_idx = cur_idx;
} while (cur_idx < (count - 1));
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 06/19] firmware: arm_ffa: Refactor addition of partition information into XArray
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (4 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 05/19] firmware: arm_ffa: Fix big-endian support in __ffa_partition_info_regs_get() Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 07/19] firmware: arm_ffa: Handle the presence of host partition in the partition info Sudeep Holla
` (13 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
From: Viresh Kumar <viresh.kumar@linaro.org>
Move the common code handling addition of the FF-A partition information
into the XArray as a new routine. No functional change.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 47 ++++++++++++++++++---------------------
1 file changed, 22 insertions(+), 25 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 87e106c728b89f3ce7c11219cf7cad9cc166dda2..2994b5ee63bc7feafc15e535cf8a2d46e6003968 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -1423,11 +1423,30 @@ static struct notifier_block ffa_bus_nb = {
.notifier_call = ffa_bus_notifier,
};
+static int ffa_xa_add_partition_info(int vm_id)
+{
+ struct ffa_dev_part_info *info;
+ int ret;
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ rwlock_init(&info->rw_lock);
+ ret = xa_insert(&drv_info->partition_info, vm_id, info, GFP_KERNEL);
+ if (ret) {
+ pr_err("%s: failed to save partition ID 0x%x - ret:%d. Abort.\n",
+ __func__, vm_id, ret);
+ kfree(info);
+ }
+
+ return ret;
+}
+
static int ffa_setup_partitions(void)
{
int count, idx, ret;
struct ffa_device *ffa_dev;
- struct ffa_dev_part_info *info;
struct ffa_partition_info *pbuf, *tpbuf;
if (drv_info->version == FFA_VERSION_1_0) {
@@ -1461,39 +1480,17 @@ static int ffa_setup_partitions(void)
!(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC))
ffa_mode_32bit_set(ffa_dev);
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info) {
+ if (ffa_xa_add_partition_info(ffa_dev->vm_id)) {
ffa_device_unregister(ffa_dev);
continue;
}
- rwlock_init(&info->rw_lock);
- ret = xa_insert(&drv_info->partition_info, tpbuf->id,
- info, GFP_KERNEL);
- if (ret) {
- pr_err("%s: failed to save partition ID 0x%x - ret:%d\n",
- __func__, tpbuf->id, ret);
- ffa_device_unregister(ffa_dev);
- kfree(info);
- }
}
kfree(pbuf);
/* Allocate for the host */
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info) {
- /* Already registered devices are freed on bus_exit */
- ffa_partitions_cleanup();
- return -ENOMEM;
- }
-
- rwlock_init(&info->rw_lock);
- ret = xa_insert(&drv_info->partition_info, drv_info->vm_id,
- info, GFP_KERNEL);
+ ret = ffa_xa_add_partition_info(drv_info->vm_id);
if (ret) {
- pr_err("%s: failed to save Host partition ID 0x%x - ret:%d. Abort.\n",
- __func__, drv_info->vm_id, ret);
- kfree(info);
/* Already registered devices are freed on bus_exit */
ffa_partitions_cleanup();
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 07/19] firmware: arm_ffa: Handle the presence of host partition in the partition info
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (5 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 06/19] firmware: arm_ffa: Refactor addition of partition information into XArray Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 08/19] firmware: arm_ffa: Unregister the FF-A devices when cleaning up the partitions Sudeep Holla
` (12 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Currently it is assumed that the firmware doesn't present the host
partition in the list of partitions presented as part of the response
to PARTITION_INFO_GET from the firmware. However, there are few
platforms that prefer to present the same in the list of partitions.
It is not manadatory but not restricted as well.
So handle the same by making sure to check the presence of the host
VM ID in the XArray partition information maintained/managed in the
driver before attempting to add it.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 2994b5ee63bc7feafc15e535cf8a2d46e6003968..320ae654cb968ef573995764d9d35c027d74a33b 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -1488,6 +1488,10 @@ static int ffa_setup_partitions(void)
kfree(pbuf);
+ /* Check if the host is already added as part of partition info */
+ if (xa_load(&drv_info->partition_info, drv_info->vm_id))
+ return 0;
+
/* Allocate for the host */
ret = ffa_xa_add_partition_info(drv_info->vm_id);
if (ret) {
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 08/19] firmware: arm_ffa: Unregister the FF-A devices when cleaning up the partitions
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (6 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 07/19] firmware: arm_ffa: Handle the presence of host partition in the partition info Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 09/19] firmware: arm_ffa: Helper to check if a partition can receive REQUEST2 messages Sudeep Holla
` (11 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Both the FF-A core and the bus were in a single module before the
commit 18c250bd7ed0 ("firmware: arm_ffa: Split bus and driver into distinct modules").
The arm_ffa_bus_exit() takes care of unregistering all the FF-A devices.
Now that there are 2 distinct modules, if the core driver is unloaded and
reloaded, it will end up adding duplicate FF-A devices as the previously
registered devices weren't unregistered when we cleaned up the modules.
Fix the same by unregistering all the FF-A devices on the FF-A bus during
the cleaning up of the partitions and hence the cleanup of the module.
Fixes: 18c250bd7ed0 ("firmware: arm_ffa: Split bus and driver into distinct modules")
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/bus.c | 3 ++-
drivers/firmware/arm_ffa/driver.c | 7 ++++---
include/linux/arm_ffa.h | 3 +++
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c
index a90e2faa990219574ff20b8f573dbb7ca76137d9..98118823cf84969480fc25c937881f9b773a38c2 100644
--- a/drivers/firmware/arm_ffa/bus.c
+++ b/drivers/firmware/arm_ffa/bus.c
@@ -160,11 +160,12 @@ static int __ffa_devices_unregister(struct device *dev, void *data)
return 0;
}
-static void ffa_devices_unregister(void)
+void ffa_devices_unregister(void)
{
bus_for_each_dev(&ffa_bus_type, NULL, NULL,
__ffa_devices_unregister);
}
+EXPORT_SYMBOL_GPL(ffa_devices_unregister);
bool ffa_device_is_valid(struct ffa_device *ffa_dev)
{
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 320ae654cb968ef573995764d9d35c027d74a33b..15305920ca9f2bcc72ac7453080f5c10430a3e26 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -1494,10 +1494,8 @@ static int ffa_setup_partitions(void)
/* Allocate for the host */
ret = ffa_xa_add_partition_info(drv_info->vm_id);
- if (ret) {
- /* Already registered devices are freed on bus_exit */
+ if (ret)
ffa_partitions_cleanup();
- }
return ret;
}
@@ -1507,6 +1505,9 @@ static void ffa_partitions_cleanup(void)
struct ffa_dev_part_info *info;
unsigned long idx;
+ /* Clean up/free all registered devices */
+ ffa_devices_unregister();
+
xa_for_each(&drv_info->partition_info, idx, info) {
xa_erase(&drv_info->partition_info, idx);
kfree(info);
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index e8b8ae8b192ab11d5550c16fd33fa9d192b07f67..ca2ad5b0ac4309052d55dcf546d29423bbd40a67 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -176,6 +176,7 @@ void ffa_device_unregister(struct ffa_device *ffa_dev);
int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
const char *mod_name);
void ffa_driver_unregister(struct ffa_driver *driver);
+void ffa_devices_unregister(void);
bool ffa_device_is_valid(struct ffa_device *ffa_dev);
#else
@@ -188,6 +189,8 @@ ffa_device_register(const struct ffa_partition_info *part_info,
static inline void ffa_device_unregister(struct ffa_device *dev) {}
+static inline void ffa_devices_unregister(void) {}
+
static inline int
ffa_driver_register(struct ffa_driver *driver, struct module *owner,
const char *mod_name)
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 09/19] firmware: arm_ffa: Helper to check if a partition can receive REQUEST2 messages
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (7 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 08/19] firmware: arm_ffa: Unregister the FF-A devices when cleaning up the partitions Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 10/19] firmware: arm_ffa: Add support for passing UUID in FFA_MSG_SEND2 Sudeep Holla
` (10 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Add a helper that allows FF-A drivers to check if the partition can
receive the direct requests via the FFA_MSG_SEND_DIRECT_REQ2 ABI.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
include/linux/arm_ffa.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index ca2ad5b0ac4309052d55dcf546d29423bbd40a67..761ea8fe3bb6080c893a5eb365358b62d6a4f3ff 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -240,6 +240,10 @@ struct ffa_partition_info {
#define FFA_PARTITION_NOTIFICATION_RECV BIT(3)
/* partition runs in the AArch64 execution state. */
#define FFA_PARTITION_AARCH64_EXEC BIT(8)
+/* partition supports receipt of direct request2 */
+#define FFA_PARTITION_DIRECT_REQ2_RECV BIT(9)
+/* partition can send direct request2. */
+#define FFA_PARTITION_DIRECT_REQ2_SEND BIT(10)
u32 properties;
uuid_t uuid;
};
@@ -259,6 +263,10 @@ bool ffa_partition_check_property(struct ffa_device *dev, u32 property)
#define ffa_partition_supports_direct_recv(dev) \
ffa_partition_check_property(dev, FFA_PARTITION_DIRECT_RECV)
+#define ffa_partition_supports_direct_req2_recv(dev) \
+ (ffa_partition_check_property(dev, FFA_PARTITION_DIRECT_REQ2_RECV) && \
+ !dev->mode_32bit)
+
/* For use with FFA_MSG_SEND_DIRECT_{REQ,RESP} which pass data via registers */
struct ffa_send_direct_data {
unsigned long data0; /* w3/x3 */
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 10/19] firmware: arm_ffa: Add support for passing UUID in FFA_MSG_SEND2
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (8 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 09/19] firmware: arm_ffa: Helper to check if a partition can receive REQUEST2 messages Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 11/19] firmware: arm_ffa: Upgrade FF-A version to v1.2 in the driver Sudeep Holla
` (9 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
FF-A v1.2 introduces UUID field in partition message header used in
FFA_MSG_SEND2 to enable partitions/endpoints exposing multiple UUIDs.
Add the support for passing UUID in FFA_MSG_SEND2.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 7 ++++---
include/linux/arm_ffa.h | 1 +
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 15305920ca9f2bcc72ac7453080f5c10430a3e26..545b1772df0095787b20332a7d5189c71bd5cacd 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -484,9 +484,9 @@ static int ffa_msg_send_direct_req(u16 src_id, u16 dst_id, bool mode_32bit,
return -EINVAL;
}
-static int ffa_msg_send2(u16 src_id, u16 dst_id, void *buf, size_t sz)
+static int ffa_msg_send2(struct ffa_device *dev, u16 src_id, void *buf, size_t sz)
{
- u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id);
+ u32 src_dst_ids = PACK_TARGET_INFO(src_id, dev->vm_id);
struct ffa_indirect_msg_hdr *msg;
ffa_value_t ret;
int retval = 0;
@@ -502,6 +502,7 @@ static int ffa_msg_send2(u16 src_id, u16 dst_id, void *buf, size_t sz)
msg->offset = sizeof(*msg);
msg->send_recv_id = src_dst_ids;
msg->size = sz;
+ uuid_copy(&msg->uuid, &dev->uuid);
memcpy((u8 *)msg + msg->offset, buf, sz);
/* flags = 0, sender VMID = 0 works for both physical/virtual NS */
@@ -1054,7 +1055,7 @@ static int ffa_sync_send_receive(struct ffa_device *dev,
static int ffa_indirect_msg_send(struct ffa_device *dev, void *buf, size_t sz)
{
- return ffa_msg_send2(drv_info->vm_id, dev->vm_id, buf, sz);
+ return ffa_msg_send2(dev, drv_info->vm_id, buf, sz);
}
static int ffa_sync_send_receive2(struct ffa_device *dev,
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index 761ea8fe3bb6080c893a5eb365358b62d6a4f3ff..bd78deeff284e2f46d42cfc7af218f4a0f3d1478 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -282,6 +282,7 @@ struct ffa_indirect_msg_hdr {
u32 offset;
u32 send_recv_id;
u32 size;
+ uuid_t uuid;
};
/* For use with FFA_MSG_SEND_DIRECT_{REQ,RESP}2 which pass data via registers */
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 11/19] firmware: arm_ffa: Upgrade FF-A version to v1.2 in the driver
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (9 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 10/19] firmware: arm_ffa: Add support for passing UUID in FFA_MSG_SEND2 Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 12/19] firmware: arm_ffa: Reject higher major version as incompatible Sudeep Holla
` (8 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
The basic and mandatory features of FF-A v1.2 are all supported now.
The driver supported version can be bumped from v1.1 to v1.2
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 2 +-
include/linux/arm_ffa.h | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 545b1772df0095787b20332a7d5189c71bd5cacd..d8421a32a92fed6d56770cba282ea55b2571b155 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -44,7 +44,7 @@
#include "common.h"
-#define FFA_DRIVER_VERSION FFA_VERSION_1_1
+#define FFA_DRIVER_VERSION FFA_VERSION_1_2
#define FFA_MIN_VERSION FFA_VERSION_1_0
#define SENDER_ID_MASK GENMASK(31, 16)
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index bd78deeff284e2f46d42cfc7af218f4a0f3d1478..4fcbdc70cbc985eabb90733329c974384d229053 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -112,6 +112,7 @@
FIELD_PREP(FFA_MINOR_VERSION_MASK, (minor)))
#define FFA_VERSION_1_0 FFA_PACK_VERSION_INFO(1, 0)
#define FFA_VERSION_1_1 FFA_PACK_VERSION_INFO(1, 1)
+#define FFA_VERSION_1_2 FFA_PACK_VERSION_INFO(1, 2)
/**
* FF-A specification mentions explicitly about '4K pages'. This should
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 12/19] firmware: arm_ffa: Reject higher major version as incompatible
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (10 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 11/19] firmware: arm_ffa: Upgrade FF-A version to v1.2 in the driver Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 13/19] firmware: arm_ffa: Remove unnecessary declaration of ffa_partitions_cleanup() Sudeep Holla
` (7 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
When the firmware compatibility was handled previously in the commit
8e3f9da608f1 ("firmware: arm_ffa: Handle compatibility with different firmware versions"),
we only addressed firmware versions that have higher minor versions
compared to the driver version which is should be considered compatible
unless the firmware returns NOT_SUPPORTED.
However, if the firmware reports higher major version than the driver
supported, we need to reject it. If the firmware can work in a compatible
mode with the driver requested version, it must return the same major
version as requested.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index d8421a32a92fed6d56770cba282ea55b2571b155..ad2f6b410e4431bb133fa0f05dd3eec802f5ee07 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -150,6 +150,14 @@ static int ffa_version_check(u32 *version)
return -EOPNOTSUPP;
}
+ if (FFA_MAJOR_VERSION(ver.a0) > FFA_MAJOR_VERSION(FFA_DRIVER_VERSION)) {
+ pr_err("Incompatible v%d.%d! Latest supported v%d.%d\n",
+ FFA_MAJOR_VERSION(ver.a0), FFA_MINOR_VERSION(ver.a0),
+ FFA_MAJOR_VERSION(FFA_DRIVER_VERSION),
+ FFA_MINOR_VERSION(FFA_DRIVER_VERSION));
+ return -EINVAL;
+ }
+
if (ver.a0 < FFA_MIN_VERSION) {
pr_err("Incompatible v%d.%d! Earliest supported v%d.%d\n",
FFA_MAJOR_VERSION(ver.a0), FFA_MINOR_VERSION(ver.a0),
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 13/19] firmware: arm_ffa: Remove unnecessary declaration of ffa_partitions_cleanup()
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (11 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 12/19] firmware: arm_ffa: Reject higher major version as incompatible Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 14/19] firmware: arm_ffa: Refactoring to prepare for framework notification support Sudeep Holla
` (6 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
In order to keep the uniformity, just move the ffa_partitions_cleanup()
before it's first usage and drop the unnecessary forward declaration.
No functional change.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 33 ++++++++++++++++-----------------
1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index ad2f6b410e4431bb133fa0f05dd3eec802f5ee07..43e033edd6c7cd16322c204e882a84cfe45abbba 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -114,7 +114,6 @@ struct ffa_drv_info {
};
static struct ffa_drv_info *drv_info;
-static void ffa_partitions_cleanup(void);
/*
* The driver must be able to support all the versions from the earliest
@@ -1452,6 +1451,22 @@ static int ffa_xa_add_partition_info(int vm_id)
return ret;
}
+static void ffa_partitions_cleanup(void)
+{
+ struct ffa_dev_part_info *info;
+ unsigned long idx;
+
+ /* Clean up/free all registered devices */
+ ffa_devices_unregister();
+
+ xa_for_each(&drv_info->partition_info, idx, info) {
+ xa_erase(&drv_info->partition_info, idx);
+ kfree(info);
+ }
+
+ xa_destroy(&drv_info->partition_info);
+}
+
static int ffa_setup_partitions(void)
{
int count, idx, ret;
@@ -1509,22 +1524,6 @@ static int ffa_setup_partitions(void)
return ret;
}
-static void ffa_partitions_cleanup(void)
-{
- struct ffa_dev_part_info *info;
- unsigned long idx;
-
- /* Clean up/free all registered devices */
- ffa_devices_unregister();
-
- xa_for_each(&drv_info->partition_info, idx, info) {
- xa_erase(&drv_info->partition_info, idx);
- kfree(info);
- }
-
- xa_destroy(&drv_info->partition_info);
-}
-
/* FFA FEATURE IDs */
#define FFA_FEAT_NOTIFICATION_PENDING_INT (1)
#define FFA_FEAT_SCHEDULE_RECEIVER_INT (2)
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 14/19] firmware: arm_ffa: Refactoring to prepare for framework notification support
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (12 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 13/19] firmware: arm_ffa: Remove unnecessary declaration of ffa_partitions_cleanup() Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 15/19] firmware: arm_ffa: Stash ffa_device instead of notify_type in notifier_cb_info Sudeep Holla
` (5 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Currently, the framework notifications are not supported at all.
handle_notif_callbacks() doesn't handle them though it is called with
framework bitmap. Make that explicit by adding checks for the same.
Also, we need to further classify the framework notifications as Secure
Partition Manager(SPM) and NonSecure Hypervisor(NS_HYP). Extend/change
notify_type enumeration to accommodate all the 4 type and rejig the
values so that it can be reused in the bitmap enable mask macros.
While at this, move ffa_notify_type_get() so that it can be used in
notifier_hash_node_get() in the future.
No functional change.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 57 +++++++++++++++++++++++----------------
1 file changed, 34 insertions(+), 23 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 43e033edd6c7cd16322c204e882a84cfe45abbba..0abbf08bc8d39c701947366bdf9c8fac8e64cf64 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -807,6 +807,13 @@ static int ffa_notification_bitmap_destroy(void)
return 0;
}
+enum notify_type {
+ SECURE_PARTITION,
+ NON_SECURE_VM,
+ SPM_FRAMEWORK,
+ NS_HYP_FRAMEWORK,
+};
+
#define NOTIFICATION_LOW_MASK GENMASK(31, 0)
#define NOTIFICATION_HIGH_MASK GENMASK(63, 32)
#define NOTIFICATION_BITMAP_HIGH(x) \
@@ -830,10 +837,17 @@ static int ffa_notification_bitmap_destroy(void)
#define MAX_IDS_32 10
#define PER_VCPU_NOTIFICATION_FLAG BIT(0)
-#define SECURE_PARTITION_BITMAP BIT(0)
-#define NON_SECURE_VM_BITMAP BIT(1)
-#define SPM_FRAMEWORK_BITMAP BIT(2)
-#define NS_HYP_FRAMEWORK_BITMAP BIT(3)
+#define SECURE_PARTITION_BITMAP_ENABLE BIT(SECURE_PARTITION)
+#define NON_SECURE_VM_BITMAP_ENABLE BIT(NON_SECURE_VM)
+#define SPM_FRAMEWORK_BITMAP_ENABLE BIT(SPM_FRAMEWORK)
+#define NS_HYP_FRAMEWORK_BITMAP_ENABLE BIT(NS_HYP_FRAMEWORK)
+#define FFA_BITMAP_ENABLE_MASK \
+ (SECURE_PARTITION_BITMAP_ENABLE | SPM_FRAMEWORK_BITMAP_ENABLE)
+
+#define FFA_SECURE_PARTITION_ID_FLAG BIT(15)
+
+#define SPM_FRAMEWORK_BITMAP(x) NOTIFICATION_BITMAP_LOW(x)
+#define NS_HYP_FRAMEWORK_BITMAP(x) NOTIFICATION_BITMAP_HIGH(x)
static int ffa_notification_bind_common(u16 dst_id, u64 bitmap,
u32 flags, bool is_bind)
@@ -1098,16 +1112,8 @@ static int ffa_memory_lend(struct ffa_mem_ops_args *args)
return ffa_memory_ops(FFA_MEM_LEND, args);
}
-#define FFA_SECURE_PARTITION_ID_FLAG BIT(15)
-
#define ffa_notifications_disabled() (!drv_info->notif_enabled)
-enum notify_type {
- NON_SECURE_VM,
- SECURE_PARTITION,
- FRAMEWORK,
-};
-
struct notifier_cb_info {
struct hlist_node hnode;
ffa_notifier_cb cb;
@@ -1166,6 +1172,14 @@ static int ffa_notification_unbind(u16 dst_id, u64 bitmap)
return ffa_notification_bind_common(dst_id, bitmap, 0, false);
}
+static enum notify_type ffa_notify_type_get(u16 vm_id)
+{
+ if (vm_id & FFA_SECURE_PARTITION_ID_FLAG)
+ return SECURE_PARTITION;
+ else
+ return NON_SECURE_VM;
+}
+
/* Should be called while the notify_lock is taken */
static struct notifier_cb_info *
notifier_hash_node_get(u16 notify_id, enum notify_type type)
@@ -1209,14 +1223,6 @@ update_notifier_cb(int notify_id, enum notify_type type, ffa_notifier_cb cb,
return 0;
}
-static enum notify_type ffa_notify_type_get(u16 vm_id)
-{
- if (vm_id & FFA_SECURE_PARTITION_ID_FLAG)
- return SECURE_PARTITION;
- else
- return NON_SECURE_VM;
-}
-
static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
{
int rc;
@@ -1299,6 +1305,9 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type)
int notify_id;
struct notifier_cb_info *cb_info = NULL;
+ if (type == SPM_FRAMEWORK || type == NS_HYP_FRAMEWORK)
+ return;
+
for (notify_id = 0; notify_id <= FFA_MAX_NOTIFICATIONS && bitmap;
notify_id++, bitmap >>= 1) {
if (!(bitmap & 1))
@@ -1318,16 +1327,18 @@ static void notif_get_and_handle(void *unused)
int rc;
struct ffa_notify_bitmaps bitmaps;
- rc = ffa_notification_get(SECURE_PARTITION_BITMAP |
- SPM_FRAMEWORK_BITMAP, &bitmaps);
+ rc = ffa_notification_get(FFA_BITMAP_ENABLE_MASK, &bitmaps);
if (rc) {
pr_err("Failed to retrieve notifications with %d!\n", rc);
return;
}
+ handle_notif_callbacks(SPM_FRAMEWORK_BITMAP(bitmaps.arch_map),
+ SPM_FRAMEWORK);
+ handle_notif_callbacks(NS_HYP_FRAMEWORK_BITMAP(bitmaps.arch_map),
+ NS_HYP_FRAMEWORK);
handle_notif_callbacks(bitmaps.vm_map, NON_SECURE_VM);
handle_notif_callbacks(bitmaps.sp_map, SECURE_PARTITION);
- handle_notif_callbacks(bitmaps.arch_map, FRAMEWORK);
}
static void
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 15/19] firmware: arm_ffa: Stash ffa_device instead of notify_type in notifier_cb_info
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (13 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 14/19] firmware: arm_ffa: Refactoring to prepare for framework notification support Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 16/19] firmware: arm_ffa: Add support for {un,}registration of framework notifications Sudeep Holla
` (4 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Currently, we store the type of the notification in the notifier_cb_info
structure that is put into the hast list to identify if the notification
block is for the secure partition or the non secure VM.
In order to support framework notifications to reuse the hash list and
to avoid creating one for each time, we need store the ffa_device pointer
itself as the same notification ID in framework notifications can be
registered by multiple FF-A devices.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 0abbf08bc8d39c701947366bdf9c8fac8e64cf64..5863272f45d9c075d8e86d45a90ac6b1fb743c98 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -1116,9 +1116,9 @@ static int ffa_memory_lend(struct ffa_mem_ops_args *args)
struct notifier_cb_info {
struct hlist_node hnode;
+ struct ffa_device *dev;
ffa_notifier_cb cb;
void *cb_data;
- enum notify_type type;
};
static int ffa_sched_recv_cb_update(u16 part_id, ffa_sched_recv_cb callback,
@@ -1187,17 +1187,18 @@ notifier_hash_node_get(u16 notify_id, enum notify_type type)
struct notifier_cb_info *node;
hash_for_each_possible(drv_info->notifier_hash, node, hnode, notify_id)
- if (type == node->type)
+ if (type == ffa_notify_type_get(node->dev->vm_id))
return node;
return NULL;
}
static int
-update_notifier_cb(int notify_id, enum notify_type type, ffa_notifier_cb cb,
+update_notifier_cb(struct ffa_device *dev, int notify_id, ffa_notifier_cb cb,
void *cb_data, bool is_registration)
{
struct notifier_cb_info *cb_info = NULL;
+ enum notify_type type = ffa_notify_type_get(dev->vm_id);
bool cb_found;
cb_info = notifier_hash_node_get(notify_id, type);
@@ -1211,7 +1212,7 @@ update_notifier_cb(int notify_id, enum notify_type type, ffa_notifier_cb cb,
if (!cb_info)
return -ENOMEM;
- cb_info->type = type;
+ cb_info->dev = dev;
cb_info->cb = cb;
cb_info->cb_data = cb_data;
@@ -1226,7 +1227,6 @@ update_notifier_cb(int notify_id, enum notify_type type, ffa_notifier_cb cb,
static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
{
int rc;
- enum notify_type type = ffa_notify_type_get(dev->vm_id);
if (ffa_notifications_disabled())
return -EOPNOTSUPP;
@@ -1236,7 +1236,7 @@ static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
mutex_lock(&drv_info->notify_lock);
- rc = update_notifier_cb(notify_id, type, NULL, NULL, false);
+ rc = update_notifier_cb(dev, notify_id, NULL, NULL, false);
if (rc) {
pr_err("Could not unregister notification callback\n");
mutex_unlock(&drv_info->notify_lock);
@@ -1255,7 +1255,6 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
{
int rc;
u32 flags = 0;
- enum notify_type type = ffa_notify_type_get(dev->vm_id);
if (ffa_notifications_disabled())
return -EOPNOTSUPP;
@@ -1274,7 +1273,7 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
return rc;
}
- rc = update_notifier_cb(notify_id, type, cb, cb_data, true);
+ rc = update_notifier_cb(dev, notify_id, cb, cb_data, true);
if (rc) {
pr_err("Failed to register callback for %d - %d\n",
notify_id, rc);
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 16/19] firmware: arm_ffa: Add support for {un,}registration of framework notifications
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (14 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 15/19] firmware: arm_ffa: Stash ffa_device instead of notify_type in notifier_cb_info Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 17/19] firmware: arm_ffa: Add support for handling " Sudeep Holla
` (3 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Framework notifications are doorbells that are rung by the partition
managers to signal common events to an endpoint. These doorbells cannot
be rung by an endpoint directly. A partition manager can signal a
Framework notification in response to an FF-A ABI invocation by an
endpoint.
Two additional notify_ops interface is being added for any FF-A device/
driver to register and unregister for such a framework notifications.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 113 +++++++++++++++++++++++++++++++-------
include/linux/arm_ffa.h | 5 ++
2 files changed, 97 insertions(+), 21 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 5863272f45d9c075d8e86d45a90ac6b1fb743c98..a889ad6d94ac499cff869a138970c9dc7ae0a1f9 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -1117,6 +1117,7 @@ static int ffa_memory_lend(struct ffa_mem_ops_args *args)
struct notifier_cb_info {
struct hlist_node hnode;
struct ffa_device *dev;
+ ffa_fwk_notifier_cb fwk_cb;
ffa_notifier_cb cb;
void *cb_data;
};
@@ -1180,28 +1181,61 @@ static enum notify_type ffa_notify_type_get(u16 vm_id)
return NON_SECURE_VM;
}
-/* Should be called while the notify_lock is taken */
+/* notifier_hnode_get* should be called with notify_lock held */
static struct notifier_cb_info *
-notifier_hash_node_get(u16 notify_id, enum notify_type type)
+notifier_hnode_get_by_vmid(u16 notify_id, int vmid)
{
struct notifier_cb_info *node;
hash_for_each_possible(drv_info->notifier_hash, node, hnode, notify_id)
- if (type == ffa_notify_type_get(node->dev->vm_id))
+ if (node->fwk_cb && vmid == node->dev->vm_id)
+ return node;
+
+ return NULL;
+}
+
+static struct notifier_cb_info *
+notifier_hnode_get_by_vmid_uuid(u16 notify_id, int vmid, const uuid_t *uuid)
+{
+ struct notifier_cb_info *node;
+
+ if (uuid_is_null(uuid))
+ return notifier_hnode_get_by_vmid(notify_id, vmid);
+
+ hash_for_each_possible(drv_info->notifier_hash, node, hnode, notify_id)
+ if (node->fwk_cb && vmid == node->dev->vm_id &&
+ uuid_equal(&node->dev->uuid, uuid))
+ return node;
+
+ return NULL;
+}
+
+static struct notifier_cb_info *
+notifier_hnode_get_by_type(u16 notify_id, enum notify_type type)
+{
+ struct notifier_cb_info *node;
+
+ hash_for_each_possible(drv_info->notifier_hash, node, hnode, notify_id)
+ if (node->cb && type == ffa_notify_type_get(node->dev->vm_id))
return node;
return NULL;
}
static int
-update_notifier_cb(struct ffa_device *dev, int notify_id, ffa_notifier_cb cb,
- void *cb_data, bool is_registration)
+update_notifier_cb(struct ffa_device *dev, int notify_id, void *cb,
+ void *cb_data, bool is_registration, bool is_framework)
{
struct notifier_cb_info *cb_info = NULL;
enum notify_type type = ffa_notify_type_get(dev->vm_id);
bool cb_found;
- cb_info = notifier_hash_node_get(notify_id, type);
+ if (is_framework)
+ cb_info = notifier_hnode_get_by_vmid_uuid(notify_id, dev->vm_id,
+ &dev->uuid);
+ else
+ cb_info = notifier_hnode_get_by_type(notify_id, type);
+
cb_found = !!cb_info;
if (!(is_registration ^ cb_found))
@@ -1213,8 +1247,11 @@ update_notifier_cb(struct ffa_device *dev, int notify_id, ffa_notifier_cb cb,
return -ENOMEM;
cb_info->dev = dev;
- cb_info->cb = cb;
cb_info->cb_data = cb_data;
+ if (is_framework)
+ cb_info->fwk_cb = cb;
+ else
+ cb_info->cb = cb;
hash_add(drv_info->notifier_hash, &cb_info->hnode, notify_id);
} else {
@@ -1224,7 +1261,8 @@ update_notifier_cb(struct ffa_device *dev, int notify_id, ffa_notifier_cb cb,
return 0;
}
-static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
+static int __ffa_notify_relinquish(struct ffa_device *dev, int notify_id,
+ bool is_framework)
{
int rc;
@@ -1236,22 +1274,35 @@ static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
mutex_lock(&drv_info->notify_lock);
- rc = update_notifier_cb(dev, notify_id, NULL, NULL, false);
+ rc = update_notifier_cb(dev, notify_id, NULL, NULL, false,
+ is_framework);
if (rc) {
pr_err("Could not unregister notification callback\n");
mutex_unlock(&drv_info->notify_lock);
return rc;
}
- rc = ffa_notification_unbind(dev->vm_id, BIT(notify_id));
+ if (!is_framework)
+ rc = ffa_notification_unbind(dev->vm_id, BIT(notify_id));
mutex_unlock(&drv_info->notify_lock);
return rc;
}
-static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
- ffa_notifier_cb cb, void *cb_data, int notify_id)
+static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
+{
+ return __ffa_notify_relinquish(dev, notify_id, false);
+}
+
+static int ffa_fwk_notify_relinquish(struct ffa_device *dev, int notify_id)
+{
+ return __ffa_notify_relinquish(dev, notify_id, true);
+}
+
+static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
+ void *cb, void *cb_data,
+ int notify_id, bool is_framework)
{
int rc;
u32 flags = 0;
@@ -1264,26 +1315,44 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
mutex_lock(&drv_info->notify_lock);
- if (is_per_vcpu)
- flags = PER_VCPU_NOTIFICATION_FLAG;
+ if (!is_framework) {
+ if (is_per_vcpu)
+ flags = PER_VCPU_NOTIFICATION_FLAG;
- rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags);
- if (rc) {
- mutex_unlock(&drv_info->notify_lock);
- return rc;
+ rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags);
+ if (rc) {
+ mutex_unlock(&drv_info->notify_lock);
+ return rc;
+ }
}
- rc = update_notifier_cb(dev, notify_id, cb, cb_data, true);
+ rc = update_notifier_cb(dev, notify_id, cb, cb_data, true,
+ is_framework);
if (rc) {
pr_err("Failed to register callback for %d - %d\n",
notify_id, rc);
- ffa_notification_unbind(dev->vm_id, BIT(notify_id));
+ if (!is_framework)
+ ffa_notification_unbind(dev->vm_id, BIT(notify_id));
}
mutex_unlock(&drv_info->notify_lock);
return rc;
}
+static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
+ ffa_notifier_cb cb, void *cb_data, int notify_id)
+{
+ return __ffa_notify_request(dev, is_per_vcpu, cb, cb_data, notify_id,
+ false);
+}
+
+static int
+ffa_fwk_notify_request(struct ffa_device *dev, ffa_fwk_notifier_cb cb,
+ void *cb_data, int notify_id)
+{
+ return __ffa_notify_request(dev, false, cb, cb_data, notify_id, true);
+}
+
static int ffa_notify_send(struct ffa_device *dev, int notify_id,
bool is_per_vcpu, u16 vcpu)
{
@@ -1313,7 +1382,7 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type)
continue;
mutex_lock(&drv_info->notify_lock);
- cb_info = notifier_hash_node_get(notify_id, type);
+ cb_info = notifier_hnode_get_by_type(notify_id, type);
mutex_unlock(&drv_info->notify_lock);
if (cb_info && cb_info->cb)
@@ -1386,6 +1455,8 @@ static const struct ffa_notifier_ops ffa_drv_notifier_ops = {
.sched_recv_cb_unregister = ffa_sched_recv_cb_unregister,
.notify_request = ffa_notify_request,
.notify_relinquish = ffa_notify_relinquish,
+ .fwk_notify_request = ffa_fwk_notify_request,
+ .fwk_notify_relinquish = ffa_fwk_notify_relinquish,
.notify_send = ffa_notify_send,
};
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index 4fcbdc70cbc985eabb90733329c974384d229053..5bded24dc24fea8cdcbe42bf79c7c025c3fa5f4b 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -468,6 +468,7 @@ struct ffa_cpu_ops {
typedef void (*ffa_sched_recv_cb)(u16 vcpu, bool is_per_vcpu, void *cb_data);
typedef void (*ffa_notifier_cb)(int notify_id, void *cb_data);
+typedef void (*ffa_fwk_notifier_cb)(int notify_id, void *cb_data, void *buf);
struct ffa_notifier_ops {
int (*sched_recv_cb_register)(struct ffa_device *dev,
@@ -476,6 +477,10 @@ struct ffa_notifier_ops {
int (*notify_request)(struct ffa_device *dev, bool per_vcpu,
ffa_notifier_cb cb, void *cb_data, int notify_id);
int (*notify_relinquish)(struct ffa_device *dev, int notify_id);
+ int (*fwk_notify_request)(struct ffa_device *dev,
+ ffa_fwk_notifier_cb cb, void *cb_data,
+ int notify_id);
+ int (*fwk_notify_relinquish)(struct ffa_device *dev, int notify_id);
int (*notify_send)(struct ffa_device *dev, int notify_id, bool per_vcpu,
u16 vcpu);
};
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 17/19] firmware: arm_ffa: Add support for handling framework notifications
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (15 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 16/19] firmware: arm_ffa: Add support for {un,}registration of framework notifications Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:38 ` [PATCH v3 18/19] firmware: arm_ffa: Allow multiple UUIDs per partition to register SRI callback Sudeep Holla
` (2 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Currently FF-A specification defines only one framework notification:
RX buffer full notification. This notification is signaled by the
partition manager during transmission of a partition message through
indirect messaging to,
1. Notify an endpoint that it has a pending message in its Rx buffer.
2. Inform the message receiver’s scheduler via the schedule receiver
interrupt that the receiver must be run.
In response to an FFA_MSG_SEND2 invocation by a sender endpoint, the
framework performs the following actions after the message is copied
from the Tx buffer of the sender to the Rx buffer of the receiver:
1. The notification is pended in the framework notification bitmap of
the receiver.
2. The partition manager of the endpoint that contains receiver’s
scheduler pends the schedule receiver interrupt for this endpoint.
The receiver receives the notification and copies out the message from
its Rx buffer.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 50 +++++++++++++++++++++++++++++++++------
1 file changed, 43 insertions(+), 7 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index a889ad6d94ac499cff869a138970c9dc7ae0a1f9..5441c4d8878023ad9107b185b711fd7b04224bb4 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -848,6 +848,7 @@ enum notify_type {
#define SPM_FRAMEWORK_BITMAP(x) NOTIFICATION_BITMAP_LOW(x)
#define NS_HYP_FRAMEWORK_BITMAP(x) NOTIFICATION_BITMAP_HIGH(x)
+#define FRAMEWORK_NOTIFY_RX_BUFFER_FULL BIT(0)
static int ffa_notification_bind_common(u16 dst_id, u64 bitmap,
u32 flags, bool is_bind)
@@ -1373,9 +1374,6 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type)
int notify_id;
struct notifier_cb_info *cb_info = NULL;
- if (type == SPM_FRAMEWORK || type == NS_HYP_FRAMEWORK)
- return;
-
for (notify_id = 0; notify_id <= FFA_MAX_NOTIFICATIONS && bitmap;
notify_id++, bitmap >>= 1) {
if (!(bitmap & 1))
@@ -1390,6 +1388,46 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type)
}
}
+static void handle_fwk_notif_callbacks(u32 bitmap)
+{
+ void *buf;
+ uuid_t uuid;
+ int notify_id = 0, target;
+ struct ffa_indirect_msg_hdr *msg;
+ struct notifier_cb_info *cb_info = NULL;
+
+ /* Only one framework notification defined and supported for now */
+ if (!(bitmap & FRAMEWORK_NOTIFY_RX_BUFFER_FULL))
+ return;
+
+ mutex_lock(&drv_info->rx_lock);
+
+ msg = drv_info->rx_buffer;
+ buf = kmemdup((void *)msg + msg->offset, msg->size, GFP_KERNEL);
+ if (!buf) {
+ mutex_unlock(&drv_info->rx_lock);
+ return;
+ }
+
+ target = SENDER_ID(msg->send_recv_id);
+ if (msg->offset >= sizeof(*msg))
+ uuid_copy(&uuid, &msg->uuid);
+ else
+ uuid_copy(&uuid, &uuid_null);
+
+ mutex_unlock(&drv_info->rx_lock);
+
+ ffa_rx_release();
+
+ mutex_lock(&drv_info->notify_lock);
+ cb_info = notifier_hnode_get_by_vmid_uuid(notify_id, target, &uuid);
+ mutex_unlock(&drv_info->notify_lock);
+
+ if (cb_info && cb_info->fwk_cb)
+ cb_info->fwk_cb(notify_id, cb_info->cb_data, buf);
+ kfree(buf);
+}
+
static void notif_get_and_handle(void *unused)
{
int rc;
@@ -1401,10 +1439,8 @@ static void notif_get_and_handle(void *unused)
return;
}
- handle_notif_callbacks(SPM_FRAMEWORK_BITMAP(bitmaps.arch_map),
- SPM_FRAMEWORK);
- handle_notif_callbacks(NS_HYP_FRAMEWORK_BITMAP(bitmaps.arch_map),
- NS_HYP_FRAMEWORK);
+ handle_fwk_notif_callbacks(SPM_FRAMEWORK_BITMAP(bitmaps.arch_map));
+ handle_fwk_notif_callbacks(NS_HYP_FRAMEWORK_BITMAP(bitmaps.arch_map));
handle_notif_callbacks(bitmaps.vm_map, NON_SECURE_VM);
handle_notif_callbacks(bitmaps.sp_map, SECURE_PARTITION);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 18/19] firmware: arm_ffa: Allow multiple UUIDs per partition to register SRI callback
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (16 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 17/19] firmware: arm_ffa: Add support for handling " Sudeep Holla
@ 2025-02-17 15:38 ` Sudeep Holla
2025-02-17 15:39 ` [PATCH v3 19/19] firmware: arm_ffa: Handle ffa_notification_get correctly at virtual FF-A instance Sudeep Holla
2025-02-21 11:41 ` [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:38 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
A partition can implement multiple UUIDs and currently we successfully
register each UUID service as a FF-A device. However when adding the
same partition info to the XArray which tracks the SRI callbacks more
than once, it fails.
In order to allow multiple UUIDs per partition to register SRI callbacks
the partition information stored in the XArray needs to be extended to
a listed list.
A function to remove the list of partition information in the XArray
is not added as there are no users at the time. All the partitions are
added at probe/initialisation and removed at cleanup stage.
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 159 ++++++++++++++++++++++++++++----------
1 file changed, 117 insertions(+), 42 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 5441c4d8878023ad9107b185b711fd7b04224bb4..db6334f0c532566565246173373d8f0a42c836af 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -925,27 +925,32 @@ struct ffa_dev_part_info {
ffa_sched_recv_cb callback;
void *cb_data;
rwlock_t rw_lock;
+ struct ffa_device *dev;
+ struct list_head node;
};
static void __do_sched_recv_cb(u16 part_id, u16 vcpu, bool is_per_vcpu)
{
- struct ffa_dev_part_info *partition;
+ struct ffa_dev_part_info *partition = NULL, *tmp;
ffa_sched_recv_cb callback;
+ struct list_head *phead;
void *cb_data;
- partition = xa_load(&drv_info->partition_info, part_id);
- if (!partition) {
+ phead = xa_load(&drv_info->partition_info, part_id);
+ if (!phead) {
pr_err("%s: Invalid partition ID 0x%x\n", __func__, part_id);
return;
}
- read_lock(&partition->rw_lock);
- callback = partition->callback;
- cb_data = partition->cb_data;
- read_unlock(&partition->rw_lock);
+ list_for_each_entry_safe(partition, tmp, phead, node) {
+ read_lock(&partition->rw_lock);
+ callback = partition->callback;
+ cb_data = partition->cb_data;
+ read_unlock(&partition->rw_lock);
- if (callback)
- callback(vcpu, is_per_vcpu, cb_data);
+ if (callback)
+ callback(vcpu, is_per_vcpu, cb_data);
+ }
}
static void ffa_notification_info_get(void)
@@ -1123,18 +1128,29 @@ struct notifier_cb_info {
void *cb_data;
};
-static int ffa_sched_recv_cb_update(u16 part_id, ffa_sched_recv_cb callback,
- void *cb_data, bool is_registration)
+static int
+ffa_sched_recv_cb_update(struct ffa_device *dev, ffa_sched_recv_cb callback,
+ void *cb_data, bool is_registration)
{
- struct ffa_dev_part_info *partition;
+ struct ffa_dev_part_info *partition = NULL, *tmp;
+ struct list_head *phead;
bool cb_valid;
if (ffa_notifications_disabled())
return -EOPNOTSUPP;
- partition = xa_load(&drv_info->partition_info, part_id);
+ phead = xa_load(&drv_info->partition_info, dev->vm_id);
+ if (!phead) {
+ pr_err("%s: Invalid partition ID 0x%x\n", __func__, dev->vm_id);
+ return -EINVAL;
+ }
+
+ list_for_each_entry_safe(partition, tmp, phead, node)
+ if (partition->dev == dev)
+ break;
+
if (!partition) {
- pr_err("%s: Invalid partition ID 0x%x\n", __func__, part_id);
+ pr_err("%s: No such partition ID 0x%x\n", __func__, dev->vm_id);
return -EINVAL;
}
@@ -1156,12 +1172,12 @@ static int ffa_sched_recv_cb_update(u16 part_id, ffa_sched_recv_cb callback,
static int ffa_sched_recv_cb_register(struct ffa_device *dev,
ffa_sched_recv_cb cb, void *cb_data)
{
- return ffa_sched_recv_cb_update(dev->vm_id, cb, cb_data, true);
+ return ffa_sched_recv_cb_update(dev, cb, cb_data, true);
}
static int ffa_sched_recv_cb_unregister(struct ffa_device *dev)
{
- return ffa_sched_recv_cb_update(dev->vm_id, NULL, NULL, false);
+ return ffa_sched_recv_cb_update(dev, NULL, NULL, false);
}
static int ffa_notification_bind(u16 dst_id, u64 bitmap, u32 flags)
@@ -1548,37 +1564,101 @@ static struct notifier_block ffa_bus_nb = {
.notifier_call = ffa_bus_notifier,
};
-static int ffa_xa_add_partition_info(int vm_id)
+static int ffa_xa_add_partition_info(struct ffa_device *dev)
{
struct ffa_dev_part_info *info;
- int ret;
+ struct list_head *head, *phead;
+ int ret = -ENOMEM;
+
+ phead = xa_load(&drv_info->partition_info, dev->vm_id);
+ if (phead) {
+ head = phead;
+ list_for_each_entry(info, head, node) {
+ if (info->dev == dev) {
+ pr_err("%s: duplicate dev %p part ID 0x%x\n",
+ __func__, dev, dev->vm_id);
+ return -EEXIST;
+ }
+ }
+ }
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
- return -ENOMEM;
+ return ret;
rwlock_init(&info->rw_lock);
- ret = xa_insert(&drv_info->partition_info, vm_id, info, GFP_KERNEL);
- if (ret) {
- pr_err("%s: failed to save partition ID 0x%x - ret:%d. Abort.\n",
- __func__, vm_id, ret);
- kfree(info);
+ info->dev = dev;
+
+ if (!phead) {
+ phead = kzalloc(sizeof(*phead), GFP_KERNEL);
+ if (!phead)
+ goto free_out;
+
+ INIT_LIST_HEAD(phead);
+
+ ret = xa_insert(&drv_info->partition_info, dev->vm_id, phead,
+ GFP_KERNEL);
+ if (ret) {
+ pr_err("%s: failed to save part ID 0x%x Ret:%d\n",
+ __func__, dev->vm_id, ret);
+ goto free_out;
+ }
+ }
+ list_add(&info->node, phead);
+ return 0;
+
+free_out:
+ kfree(phead);
+ kfree(info);
+ return ret;
+}
+
+static int ffa_setup_host_partition(int vm_id)
+{
+ struct ffa_partition_info buf = { 0 };
+ struct ffa_device *ffa_dev;
+ int ret;
+
+ buf.id = vm_id;
+ ffa_dev = ffa_device_register(&buf, &ffa_drv_ops);
+ if (!ffa_dev) {
+ pr_err("%s: failed to register host partition ID 0x%x\n",
+ __func__, vm_id);
+ return -EINVAL;
}
+ ret = ffa_xa_add_partition_info(ffa_dev);
+ if (ret)
+ return ret;
+
+ if (ffa_notifications_disabled())
+ return 0;
+
+ ret = ffa_sched_recv_cb_update(ffa_dev, ffa_self_notif_handle,
+ drv_info, true);
+ if (ret)
+ pr_info("Failed to register driver sched callback %d\n", ret);
+
return ret;
}
static void ffa_partitions_cleanup(void)
{
- struct ffa_dev_part_info *info;
+ struct list_head *phead;
unsigned long idx;
/* Clean up/free all registered devices */
ffa_devices_unregister();
- xa_for_each(&drv_info->partition_info, idx, info) {
+ xa_for_each(&drv_info->partition_info, idx, phead) {
+ struct ffa_dev_part_info *info, *tmp;
+
xa_erase(&drv_info->partition_info, idx);
- kfree(info);
+ list_for_each_entry_safe(info, tmp, phead, node) {
+ list_del(&info->node);
+ kfree(info);
+ }
+ kfree(phead);
}
xa_destroy(&drv_info->partition_info);
@@ -1621,7 +1701,7 @@ static int ffa_setup_partitions(void)
!(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC))
ffa_mode_32bit_set(ffa_dev);
- if (ffa_xa_add_partition_info(ffa_dev->vm_id)) {
+ if (ffa_xa_add_partition_info(ffa_dev)) {
ffa_device_unregister(ffa_dev);
continue;
}
@@ -1629,12 +1709,16 @@ static int ffa_setup_partitions(void)
kfree(pbuf);
- /* Check if the host is already added as part of partition info */
+ /*
+ * Check if the host is already added as part of partition info
+ * No multiple UUID possible for the host, so just checking if
+ * there is an entry will suffice
+ */
if (xa_load(&drv_info->partition_info, drv_info->vm_id))
return 0;
/* Allocate for the host */
- ret = ffa_xa_add_partition_info(drv_info->vm_id);
+ ret = ffa_setup_host_partition(drv_info->vm_id);
if (ret)
ffa_partitions_cleanup();
@@ -1943,19 +2027,10 @@ static int __init ffa_init(void)
ffa_notifications_setup();
ret = ffa_setup_partitions();
- if (ret) {
- pr_err("failed to setup partitions\n");
- goto cleanup_notifs;
- }
-
- ret = ffa_sched_recv_cb_update(drv_info->vm_id, ffa_self_notif_handle,
- drv_info, true);
- if (ret)
- pr_info("Failed to register driver sched callback %d\n", ret);
-
- return 0;
+ if (!ret)
+ return ret;
-cleanup_notifs:
+ pr_err("failed to setup partitions\n");
ffa_notifications_cleanup();
free_pages:
if (drv_info->tx_buffer)
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v3 19/19] firmware: arm_ffa: Handle ffa_notification_get correctly at virtual FF-A instance
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (17 preceding siblings ...)
2025-02-17 15:38 ` [PATCH v3 18/19] firmware: arm_ffa: Allow multiple UUIDs per partition to register SRI callback Sudeep Holla
@ 2025-02-17 15:39 ` Sudeep Holla
2025-02-21 11:41 ` [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-17 15:39 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Sudeep Holla, Viresh Kumar
Currently it is assumed that the driver always calls ffa_notification_get()
at the NS physical FF-A instance to request the SPMC to return pending
SP or SPM Framework notifications. However, in order to support the driver
invoking ffa_notification_get() at virtual FF-A instance, we need to make
sure correct bits are enabled in the bitmaps enable flag.
It is expected to have hypervisor framework and VM notifications bitmap
to be zero at the non-secure physical FF-A instance.
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index db6334f0c532566565246173373d8f0a42c836af..f3ca703a44413b6394559c68b12fda6a75acadf0 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -841,8 +841,12 @@ enum notify_type {
#define NON_SECURE_VM_BITMAP_ENABLE BIT(NON_SECURE_VM)
#define SPM_FRAMEWORK_BITMAP_ENABLE BIT(SPM_FRAMEWORK)
#define NS_HYP_FRAMEWORK_BITMAP_ENABLE BIT(NS_HYP_FRAMEWORK)
-#define FFA_BITMAP_ENABLE_MASK \
+#define FFA_BITMAP_SECURE_ENABLE_MASK \
(SECURE_PARTITION_BITMAP_ENABLE | SPM_FRAMEWORK_BITMAP_ENABLE)
+#define FFA_BITMAP_NS_ENABLE_MASK \
+ (NON_SECURE_VM_BITMAP_ENABLE | NS_HYP_FRAMEWORK_BITMAP_ENABLE)
+#define FFA_BITMAP_ALL_ENABLE_MASK \
+ (FFA_BITMAP_SECURE_ENABLE_MASK | FFA_BITMAP_NS_ENABLE_MASK)
#define FFA_SECURE_PARTITION_ID_FLAG BIT(15)
@@ -914,9 +918,15 @@ static int ffa_notification_get(u32 flags, struct ffa_notify_bitmaps *notify)
else if (ret.a0 != FFA_SUCCESS)
return -EINVAL; /* Something else went wrong. */
- notify->sp_map = PACK_NOTIFICATION_BITMAP(ret.a2, ret.a3);
- notify->vm_map = PACK_NOTIFICATION_BITMAP(ret.a4, ret.a5);
- notify->arch_map = PACK_NOTIFICATION_BITMAP(ret.a6, ret.a7);
+ if (flags & SECURE_PARTITION_BITMAP_ENABLE)
+ notify->sp_map = PACK_NOTIFICATION_BITMAP(ret.a2, ret.a3);
+ if (flags & NON_SECURE_VM_BITMAP_ENABLE)
+ notify->vm_map = PACK_NOTIFICATION_BITMAP(ret.a4, ret.a5);
+ if (flags & SPM_FRAMEWORK_BITMAP_ENABLE)
+ notify->arch_map = SPM_FRAMEWORK_BITMAP(ret.a6);
+ if (flags & NS_HYP_FRAMEWORK_BITMAP_ENABLE)
+ notify->arch_map = PACK_NOTIFICATION_BITMAP(notify->arch_map,
+ ret.a7);
return 0;
}
@@ -1444,12 +1454,19 @@ static void handle_fwk_notif_callbacks(u32 bitmap)
kfree(buf);
}
-static void notif_get_and_handle(void *unused)
+static void notif_get_and_handle(void *cb_data)
{
int rc;
- struct ffa_notify_bitmaps bitmaps;
+ u32 flags;
+ struct ffa_drv_info *info = cb_data;
+ struct ffa_notify_bitmaps bitmaps = { 0 };
+
+ if (info->vm_id == 0) /* Non secure physical instance */
+ flags = FFA_BITMAP_SECURE_ENABLE_MASK;
+ else
+ flags = FFA_BITMAP_ALL_ENABLE_MASK;
- rc = ffa_notification_get(FFA_BITMAP_ENABLE_MASK, &bitmaps);
+ rc = ffa_notification_get(flags, &bitmaps);
if (rc) {
pr_err("Failed to retrieve notifications with %d!\n", rc);
return;
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes
2025-02-17 15:38 [PATCH v3 00/19] firmware: arm_ffa: Framework notification support + other updates and fixes Sudeep Holla
` (18 preceding siblings ...)
2025-02-17 15:39 ` [PATCH v3 19/19] firmware: arm_ffa: Handle ffa_notification_get correctly at virtual FF-A instance Sudeep Holla
@ 2025-02-21 11:41 ` Sudeep Holla
19 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2025-02-21 11:41 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, Viresh Kumar, Sudeep Holla
On Mon, 17 Feb 2025 15:38:41 +0000, Sudeep Holla wrote:
> This bundle of changes mainly have FF-A framework notification support
> along with other minor updates and fixes.
>
> It adds support to allow multiple UUIDs per partition to register
> individual SRI callback, to handle Rx buffer full framework notification
> in particular and general framework/interface to extend in the future.
>
> [...]
Applied to sudeep.holla/linux (for-next/ffa/updates), thanks!
[01/19] firmware: arm_ffa: Replace SCMI by FF-A in the macro
https://git.kernel.org/sudeep.holla/c/1ed14652dc32
[02/19] firmware: arm_ffa: Replace UUID buffer to standard UUID format
https://git.kernel.org/sudeep.holla/c/b7c9f32614f1
[03/19] firmware: arm_ffa: Align sync_send_receive{,2} function prototypes
https://git.kernel.org/sudeep.holla/c/8768972cbbea
[04/19] firmware: arm_ffa: Fix big-endian support in __ffa_partition_info_get()
https://git.kernel.org/sudeep.holla/c/f94ebb724067
[05/19] firmware: arm_ffa: Fix big-endian support in __ffa_partition_info_regs_get()
https://git.kernel.org/sudeep.holla/c/7bc0f589c81d
[06/19] firmware: arm_ffa: Refactor addition of partition information into XArray
https://git.kernel.org/sudeep.holla/c/3c3d6767466e
[07/19] firmware: arm_ffa: Handle the presence of host partition in the partition info
https://git.kernel.org/sudeep.holla/c/2f622a8b0722
[08/19] firmware: arm_ffa: Unregister the FF-A devices when cleaning up the partitions
https://git.kernel.org/sudeep.holla/c/46dcd68aacca
[09/19] firmware: arm_ffa: Helper to check if a partition can receive REQUEST2 messages
https://git.kernel.org/sudeep.holla/c/84968e32d301
[10/19] firmware: arm_ffa: Add support for passing UUID in FFA_MSG_SEND2
https://git.kernel.org/sudeep.holla/c/910cc1acc9b4
[11/19] firmware: arm_ffa: Upgrade FF-A version to v1.2 in the driver
https://git.kernel.org/sudeep.holla/c/9fac08d9d985
[12/19] firmware: arm_ffa: Reject higher major version as incompatible
https://git.kernel.org/sudeep.holla/c/efff6a7f16b3
[13/19] firmware: arm_ffa: Remove unnecessary declaration of ffa_partitions_cleanup()
https://git.kernel.org/sudeep.holla/c/9982cabf403f
[14/19] firmware: arm_ffa: Refactoring to prepare for framework notification support
https://git.kernel.org/sudeep.holla/c/07b760e71325
[15/19] firmware: arm_ffa: Stash ffa_device instead of notify_type in notifier_cb_info
https://git.kernel.org/sudeep.holla/c/a3d73fe8ae5d
[16/19] firmware: arm_ffa: Add support for {un,}registration of framework notifications
https://git.kernel.org/sudeep.holla/c/c10debfe7f02
[17/19] firmware: arm_ffa: Add support for handling framework notifications
https://git.kernel.org/sudeep.holla/c/285a5ea0f542
[18/19] firmware: arm_ffa: Allow multiple UUIDs per partition to register SRI callback
https://git.kernel.org/sudeep.holla/c/be61da938576
[19/19] firmware: arm_ffa: Handle ffa_notification_get correctly at virtual FF-A instance
https://git.kernel.org/sudeep.holla/c/9472fe20d396
--
Regards,
Sudeep
^ permalink raw reply [flat|nested] 21+ messages in thread