mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-28 16:53:49 +00:00
firmware: arm_ffa: Fix the race around setting ffa_dev->properties
Currently, ffa_dev->properties is set after the ffa_device_register()
call return in ffa_setup_partitions(). This could potentially result in
a race where the partition's properties is accessed while probing
struct ffa_device before it is set.
Update the ffa_device_register() to receive ffa_partition_info so all
the data from the partition information received from the firmware can
be updated into the struct ffa_device before the calling device_register()
in ffa_device_register().
Fixes: e781858488
("firmware: arm_ffa: Add initial FFA bus support for device enumeration")
Signed-off-by: Levi Yun <yeoreum.yun@arm.com>
Message-Id: <20241203143109.1030514-2-yeoreum.yun@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
This commit is contained in:
parent
40384c840e
commit
6fe437cfe2
@ -187,13 +187,18 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev)
|
||||
return valid;
|
||||
}
|
||||
|
||||
struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
|
||||
const struct ffa_ops *ops)
|
||||
struct ffa_device *
|
||||
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;
|
||||
|
||||
if (!part_info)
|
||||
return NULL;
|
||||
|
||||
id = ida_alloc_min(&ffa_bus_id, 1, GFP_KERNEL);
|
||||
if (id < 0)
|
||||
return NULL;
|
||||
@ -210,9 +215,11 @@ struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
|
||||
dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id);
|
||||
|
||||
ffa_dev->id = id;
|
||||
ffa_dev->vm_id = vm_id;
|
||||
ffa_dev->vm_id = part_info->id;
|
||||
ffa_dev->properties = part_info->properties;
|
||||
ffa_dev->ops = ops;
|
||||
uuid_copy(&ffa_dev->uuid, uuid);
|
||||
import_uuid(&uuid, (u8 *)part_info->uuid);
|
||||
uuid_copy(&ffa_dev->uuid, &uuid);
|
||||
|
||||
ret = device_register(&ffa_dev->dev);
|
||||
if (ret) {
|
||||
|
@ -1387,7 +1387,6 @@ static struct notifier_block ffa_bus_nb = {
|
||||
static int ffa_setup_partitions(void)
|
||||
{
|
||||
int count, idx, ret;
|
||||
uuid_t uuid;
|
||||
struct ffa_device *ffa_dev;
|
||||
struct ffa_dev_part_info *info;
|
||||
struct ffa_partition_info *pbuf, *tpbuf;
|
||||
@ -1406,23 +1405,19 @@ static int ffa_setup_partitions(void)
|
||||
|
||||
xa_init(&drv_info->partition_info);
|
||||
for (idx = 0, tpbuf = pbuf; idx < count; idx++, tpbuf++) {
|
||||
import_uuid(&uuid, (u8 *)tpbuf->uuid);
|
||||
|
||||
/* Note that if the UUID will be uuid_null, that will require
|
||||
* ffa_bus_notifier() to find the UUID of this partition id
|
||||
* with help of ffa_device_match_uuid(). FF-A v1.1 and above
|
||||
* provides UUID here for each partition as part of the
|
||||
* discovery API and the same is passed.
|
||||
*/
|
||||
ffa_dev = ffa_device_register(&uuid, tpbuf->id, &ffa_drv_ops);
|
||||
ffa_dev = ffa_device_register(tpbuf, &ffa_drv_ops);
|
||||
if (!ffa_dev) {
|
||||
pr_err("%s: failed to register partition ID 0x%x\n",
|
||||
__func__, tpbuf->id);
|
||||
continue;
|
||||
}
|
||||
|
||||
ffa_dev->properties = tpbuf->properties;
|
||||
|
||||
if (drv_info->version > FFA_VERSION_1_0 &&
|
||||
!(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC))
|
||||
ffa_mode_32bit_set(ffa_dev);
|
||||
|
@ -166,9 +166,12 @@ static inline void *ffa_dev_get_drvdata(struct ffa_device *fdev)
|
||||
return dev_get_drvdata(&fdev->dev);
|
||||
}
|
||||
|
||||
struct ffa_partition_info;
|
||||
|
||||
#if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT)
|
||||
struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
|
||||
const struct ffa_ops *ops);
|
||||
struct ffa_device *
|
||||
ffa_device_register(const struct ffa_partition_info *part_info,
|
||||
const struct ffa_ops *ops);
|
||||
void ffa_device_unregister(struct ffa_device *ffa_dev);
|
||||
int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
|
||||
const char *mod_name);
|
||||
@ -176,9 +179,9 @@ void ffa_driver_unregister(struct ffa_driver *driver);
|
||||
bool ffa_device_is_valid(struct ffa_device *ffa_dev);
|
||||
|
||||
#else
|
||||
static inline
|
||||
struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
|
||||
const struct ffa_ops *ops)
|
||||
static inline struct ffa_device *
|
||||
ffa_device_register(const struct ffa_partition_info *part_info,
|
||||
const struct ffa_ops *ops)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user