Commit abf5422e authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'ffa-fixes-6.4' of...

Merge tag 'ffa-fixes-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes

Arm FF-A fixes for v6.4

Quite a few fixes to address set of assorted issues:
1. NULL pointer dereference if the ffa driver doesn't provide remove()
   callback as it is currently executed unconditionally
2. FF-A core probe failure on systems with v1.0 firmware as the new
   partition info get count flag is used unconditionally
3. Failure to register more than one logical partition or service within
   the same physical partition as the device name contains only VM ID
   which will be same for all but each will have unique UUID.
4. Rejection of certain memory interface transmissions by the receivers
   (secure partitions) as few MBZ fields are non-zero due to lack of
   explicit re-initialization of those fields

* tag 'ffa-fixes-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
  firmware: arm_ffa: Set reserved/MBZ fields to zero in the memory descriptors
  firmware: arm_ffa: Fix FFA device names for logical partitions
  firmware: arm_ffa: Fix usage of partition info get count flag
  firmware: arm_ffa: Check if ffa_driver remove is present before executing

Link: https://lore.kernel.org/r/20230509143453.1188753-1-sudeep.holla@arm.comSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 51bba254 111a833d
......@@ -15,6 +15,8 @@
#include "common.h"
static DEFINE_IDA(ffa_bus_id);
static int ffa_device_match(struct device *dev, struct device_driver *drv)
{
const struct ffa_device_id *id_table;
......@@ -53,7 +55,8 @@ static void ffa_device_remove(struct device *dev)
{
struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver);
ffa_drv->remove(to_ffa_dev(dev));
if (ffa_drv->remove)
ffa_drv->remove(to_ffa_dev(dev));
}
static int ffa_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
......@@ -130,6 +133,7 @@ static void ffa_release_device(struct device *dev)
{
struct ffa_device *ffa_dev = to_ffa_dev(dev);
ida_free(&ffa_bus_id, ffa_dev->id);
kfree(ffa_dev);
}
......@@ -170,18 +174,24 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev)
struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
const struct ffa_ops *ops)
{
int ret;
int id, ret;
struct device *dev;
struct ffa_device *ffa_dev;
id = ida_alloc_min(&ffa_bus_id, 1, GFP_KERNEL);
if (id < 0)
return NULL;
ffa_dev = kzalloc(sizeof(*ffa_dev), GFP_KERNEL);
if (!ffa_dev)
if (!ffa_dev) {
ida_free(&ffa_bus_id, id);
return NULL;
}
dev = &ffa_dev->dev;
dev->bus = &ffa_bus_type;
dev->release = ffa_release_device;
dev_set_name(&ffa_dev->dev, "arm-ffa-%04x", vm_id);
dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id);
ffa_dev->vm_id = vm_id;
ffa_dev->ops = ops;
......@@ -217,4 +227,5 @@ void arm_ffa_bus_exit(void)
{
ffa_devices_unregister();
bus_unregister(&ffa_bus_type);
ida_destroy(&ffa_bus_id);
}
......@@ -193,7 +193,8 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
int idx, count, flags = 0, sz, buf_sz;
ffa_value_t partition_info;
if (!buffer || !num_partitions) /* Just get the count for now */
if (drv_info->version > FFA_VERSION_1_0 &&
(!buffer || !num_partitions)) /* Just get the count for now */
flags = PARTITION_INFO_GET_RETURN_COUNT_ONLY;
mutex_lock(&drv_info->rx_lock);
......@@ -420,12 +421,17 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
ep_mem_access->receiver = args->attrs[idx].receiver;
ep_mem_access->attrs = args->attrs[idx].attrs;
ep_mem_access->composite_off = COMPOSITE_OFFSET(args->nattrs);
ep_mem_access->flag = 0;
ep_mem_access->reserved = 0;
}
mem_region->reserved_0 = 0;
mem_region->reserved_1 = 0;
mem_region->ep_count = args->nattrs;
composite = buffer + COMPOSITE_OFFSET(args->nattrs);
composite->total_pg_cnt = ffa_get_num_pages_sg(args->sg);
composite->addr_range_cnt = num_entries;
composite->reserved = 0;
length = COMPOSITE_CONSTITUENTS_OFFSET(args->nattrs, num_entries);
frag_len = COMPOSITE_CONSTITUENTS_OFFSET(args->nattrs, 0);
......@@ -460,6 +466,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
constituents->address = sg_phys(args->sg);
constituents->pg_cnt = args->sg->length / FFA_PAGE_SIZE;
constituents->reserved = 0;
constituents++;
frag_len += sizeof(struct ffa_mem_region_addr_range);
} while ((args->sg = sg_next(args->sg)));
......
......@@ -96,6 +96,7 @@
/* FFA Bus/Device/Driver related */
struct ffa_device {
u32 id;
int vm_id;
bool mode_32bit;
uuid_t uuid;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment