[PATCH 1/2] firmware: arm_ffa: Share FF-A register field definitions
From: Sudeep Holla
Date: Wed Sep 23 2026 - 08:18:37 EST
ACPI FFH and the FF-A transport driver will be interpreting the same
PARTITION_INFO_GET_REGS metadata and pack endpoint IDs using the same
bit fields. Define these fields once in arm_ffa.h instead of keeping
private copies.
Use the shared masks in the transport driver and check descriptor
lengths against the same minimum used by ACPI FFH. This keeps the ABI
encoding consistent between the two users.
Signed-off-by: Sudeep Holla <sudeep.holla@xxxxxxxxxx>
---
drivers/firmware/arm_ffa/driver.c | 48 +++++++++++--------------------
include/linux/arm_ffa.h | 19 ++++++++++++
2 files changed, 36 insertions(+), 31 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 69d5f754dce4..05306ea484df 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -55,13 +55,6 @@
#define FFA_MIN_VERSION FFA_VERSION_1_0
#define FFA_PLATFORM_NAME "arm-ffa"
-#define SENDER_ID_MASK GENMASK(31, 16)
-#define RECEIVER_ID_MASK GENMASK(15, 0)
-#define SENDER_ID(x) ((u16)(FIELD_GET(SENDER_ID_MASK, (x))))
-#define RECEIVER_ID(x) ((u16)(FIELD_GET(RECEIVER_ID_MASK, (x))))
-#define PACK_TARGET_INFO(s, r) \
- (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
-
#define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16)
#define RXTX_MAP_MIN_BUFSZ(x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
@@ -328,24 +321,16 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
return count;
}
-#define LAST_INDEX_MASK GENMASK(15, 0)
-#define CURRENT_INDEX_MASK GENMASK(31, 16)
-#define UUID_INFO_TAG_MASK GENMASK(47, 32)
-#define PARTITION_INFO_SZ_MASK GENMASK(63, 48)
-#define PARTITION_COUNT(x) ((u16)(FIELD_GET(LAST_INDEX_MASK, (x))) + 1)
-#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 PARTITION_COUNT(x) ((u16)(FIELD_GET(FFA_PART_INFO_LAST_IDX_MASK, (x))) + 1)
+#define CURRENT_INDEX(x) ((u16)(FIELD_GET(FFA_PART_INFO_CUR_IDX_MASK, (x))))
+#define UUID_INFO_TAG(x) ((u16)(FIELD_GET(FFA_PART_INFO_UUID_TAG_MASK, (x))))
+#define PARTITION_INFO_SZ(x) ((u16)(FIELD_GET(FFA_PART_INFO_DESC_SIZE_MASK, (x))))
#define FFA_PART_INFO_GET_REGS_FIRST_REG 3
-#define FFA_PART_INFO_GET_REGS_MIN_REGS_PER_DESC 3
#define FFA_PART_INFO_GET_REGS_NUM_REGS \
(sizeof(ffa_value_t) / sizeof_field(ffa_value_t, a0))
-#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))))
+#define PART_INFO_ID(x) ((u16)(FIELD_GET(FFA_PART_INFO_ID_MASK, (x))))
+#define PART_INFO_EXEC_CXT(x) ((u16)(FIELD_GET(FFA_PART_INFO_EXEC_CXT_MASK, (x))))
+#define PART_INFO_PROPERTIES(x) ((u32)(FIELD_GET(FFA_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)
@@ -383,9 +368,9 @@ __ffa_partition_info_get_regs(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
if (buf_sz % sizeof(*regs))
return -EINVAL;
- regs_per_desc = buf_sz / sizeof(*regs);
- if (regs_per_desc < FFA_PART_INFO_GET_REGS_MIN_REGS_PER_DESC)
+ if (buf_sz < FFA_PART_INFO_MIN_DESC_SIZE)
return -EINVAL;
+ regs_per_desc = buf_sz / sizeof(*regs);
nr_desc = cur_idx - start_idx + 1;
max_desc = (FFA_PART_INFO_GET_REGS_NUM_REGS -
@@ -501,7 +486,7 @@ static inline void ffa_msg_send_wait_for_completion(ffa_value_t *ret)
static int ffa_msg_send_direct_req(u16 src_id, u16 dst_id, bool mode_32bit,
struct ffa_send_direct_data *data)
{
- u32 req_id, resp_id, src_dst_ids = PACK_TARGET_INFO(src_id, dst_id);
+ u32 req_id, resp_id, src_dst_ids = ffa_pack_target_info(src_id, dst_id);
ffa_value_t ret;
if (mode_32bit) {
@@ -537,7 +522,7 @@ static int ffa_msg_send_direct_req(u16 src_id, u16 dst_id, bool mode_32bit,
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, dev->vm_id);
+ u32 src_dst_ids = ffa_pack_target_info(src_id, dev->vm_id);
struct ffa_indirect_msg_hdr *msg;
ffa_value_t ret;
int retval = 0;
@@ -571,7 +556,7 @@ static int ffa_msg_send2(struct ffa_device *dev, u16 src_id, void *buf, size_t s
static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid,
struct ffa_send_direct_data2 *data)
{
- u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id);
+ u32 src_dst_ids = ffa_pack_target_info(src_id, dst_id);
union {
uuid_t uuid;
__le64 regs[2];
@@ -897,7 +882,7 @@ enum notify_type {
#define RECEIVER_VCPU_MASK GENMASK(31, 16)
#define PACK_NOTIFICATION_GET_RECEIVER_INFO(vcpu_r, r) \
(FIELD_PREP(RECEIVER_VCPU_MASK, (vcpu_r)) | \
- FIELD_PREP(RECEIVER_ID_MASK, (r)))
+ FIELD_PREP(FFA_TARGET_INFO_RECEIVER_MASK, (r)))
#define NOTIFICATION_INFO_GET_MORE_PEND_MASK BIT(0)
#define NOTIFICATION_INFO_GET_ID_COUNT GENMASK(11, 7)
@@ -928,7 +913,7 @@ static int ffa_notification_bind_common(u16 dst_id, u64 bitmap,
u32 flags, bool is_bind)
{
ffa_value_t ret;
- u32 func, src_dst_ids = PACK_TARGET_INFO(dst_id, drv_info->vm_id);
+ u32 func, src_dst_ids = ffa_pack_target_info(dst_id, drv_info->vm_id);
func = is_bind ? FFA_NOTIFICATION_BIND : FFA_NOTIFICATION_UNBIND;
@@ -950,7 +935,7 @@ static
int ffa_notification_set(u16 src_id, u16 dst_id, u32 flags, u64 bitmap)
{
ffa_value_t ret;
- u32 src_dst_ids = PACK_TARGET_INFO(dst_id, src_id);
+ u32 src_dst_ids = ffa_pack_target_info(dst_id, src_id);
invoke_ffa_fn((ffa_value_t) {
.a0 = FFA_NOTIFICATION_SET, .a1 = src_dst_ids, .a2 = flags,
@@ -1567,7 +1552,8 @@ static void handle_fwk_notif_callbacks(u32 bitmap)
return;
}
- target = SENDER_ID(msg->send_recv_id);
+ target = FIELD_GET(FFA_TARGET_INFO_SENDER_MASK,
+ msg->send_recv_id);
if (offset >= sizeof(*msg))
uuid_copy(&uuid, &msg->uuid);
else
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index e71d83ee0aef..3831fbe244c1 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -130,6 +130,15 @@
#define FFA_FEAT_RXTX_MIN_SZ_16K 2
#define FFA_FEAT_RXTX_MIN_SZ_MASK GENMASK(1, 0)
+#define FFA_TARGET_INFO_SENDER_MASK GENMASK(31, 16)
+#define FFA_TARGET_INFO_RECEIVER_MASK GENMASK(15, 0)
+
+static inline u32 ffa_pack_target_info(u16 sender, u16 receiver)
+{
+ return FIELD_PREP(FFA_TARGET_INFO_SENDER_MASK, sender) |
+ FIELD_PREP(FFA_TARGET_INFO_RECEIVER_MASK, receiver);
+}
+
/* FFA Bus/Device/Driver related */
struct ffa_device {
u32 id;
@@ -228,6 +237,16 @@ extern const struct bus_type ffa_bus_type;
/* The FF-A 1.0 partition structure lacks the uuid[4] */
#define FFA_1_0_PARTITON_INFO_SZ (8)
+/* FFA_PARTITION_INFO_GET_REGS response fields */
+#define FFA_PART_INFO_LAST_IDX_MASK GENMASK_ULL(15, 0)
+#define FFA_PART_INFO_CUR_IDX_MASK GENMASK_ULL(31, 16)
+#define FFA_PART_INFO_UUID_TAG_MASK GENMASK_ULL(47, 32)
+#define FFA_PART_INFO_DESC_SIZE_MASK GENMASK_ULL(63, 48)
+#define FFA_PART_INFO_MIN_DESC_SIZE 24
+#define FFA_PART_INFO_ID_MASK GENMASK_ULL(15, 0)
+#define FFA_PART_INFO_EXEC_CXT_MASK GENMASK_ULL(31, 16)
+#define FFA_PART_INFO_PROPS_MASK GENMASK_ULL(63, 32)
+
/* FFA transport related */
struct ffa_partition_info {
u16 id;
--
2.43.0