Skip to content

Commit

Permalink
Merge tag 'ffa-fixes-6.4' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/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/[email protected]
Signed-off-by: Arnd Bergmann <[email protected]>
  • Loading branch information
arndb committed May 26, 2023
2 parents 51bba25 + 111a833 commit abf5422
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 5 deletions.
19 changes: 15 additions & 4 deletions drivers/firmware/arm_ffa/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -217,4 +227,5 @@ void arm_ffa_bus_exit(void)
{
ffa_devices_unregister();
bus_unregister(&ffa_bus_type);
ida_destroy(&ffa_bus_id);
}
9 changes: 8 additions & 1 deletion drivers/firmware/arm_ffa/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)));
Expand Down
1 change: 1 addition & 0 deletions include/linux/arm_ffa.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@

/* FFA Bus/Device/Driver related */
struct ffa_device {
u32 id;
int vm_id;
bool mode_32bit;
uuid_t uuid;
Expand Down

0 comments on commit abf5422

Please sign in to comment.