#define PART_INFO_EXEC_CXT_MASK GENMASK(31, 16)
#define PART_INFO_PROPS_MASK GENMASK(63, 32)
#define FFA_PART_INFO_GET_REGS_FIRST_REG 3
-#define FFA_PART_INFO_GET_REGS_REGS_PER_DESC 3
-#define FFA_PART_INFO_GET_REGS_MAX_DESC \
- (((sizeof(ffa_value_t) / sizeof_field(ffa_value_t, a0)) - \
- FFA_PART_INFO_GET_REGS_FIRST_REG) / \
- FFA_PART_INFO_GET_REGS_REGS_PER_DESC)
+#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))))
do {
__le64 *regs;
- int idx, nr_desc, buf_idx;
+ int idx, nr_desc, buf_idx, regs_per_desc, max_desc;
invoke_ffa_fn((ffa_value_t){
.a0 = FFA_PARTITION_INFO_GET_REGS,
if (cur_idx < start_idx || cur_idx >= count)
return -EINVAL;
+ buf_sz = PARTITION_INFO_SZ(partition_info.a2);
+ 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)
+ return -EINVAL;
+
nr_desc = cur_idx - start_idx + 1;
- if (nr_desc > FFA_PART_INFO_GET_REGS_MAX_DESC)
+ max_desc = (FFA_PART_INFO_GET_REGS_NUM_REGS -
+ FFA_PART_INFO_GET_REGS_FIRST_REG) / regs_per_desc;
+ if (nr_desc > max_desc)
return -EINVAL;
buf_idx = buf - buffer;
return -EINVAL;
tag = UUID_INFO_TAG(partition_info.a2);
- buf_sz = PARTITION_INFO_SZ(partition_info.a2);
- if (buf_sz > sizeof(*buffer))
- buf_sz = sizeof(*buffer);
regs = (void *)&partition_info.a3;
for (idx = 0; idx < nr_desc; idx++, buf++) {
buf->exec_ctxt = PART_INFO_EXEC_CXT(val);
buf->properties = PART_INFO_PROPERTIES(val);
uuid_copy(&buf->uuid, &uuid_regs.uuid);
- regs += 3;
+ regs += regs_per_desc;
}
start_idx = cur_idx + 1;