Arm FF-A fixes for v6.7
A bunch of fixes addressing issues around the notification support that was added this cycle. They address issue in partition IDs handling in ffa_notification_info_get(), notifications cleanup path and the size of the allocation in ffa_partitions_cleanup(). It also adds check for the notification enabled state so that the drivers registering the callbacks can be rejected if not enabled/supported. It also moves the partitions setup operation after the notification initialisation so that the driver has the correct state for notification enabled/supported before the partitions are initialised/setup. It also now allows FF-A initialisation to complete successfully even when the notification initialisation fails as it is an optional support in the specification. Initial support just allowed it only if the firmware didn't support notifications. Finally, it also adds a fix for smatch warning by declaring ffa_bus_type structure in the header. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEunHlEgbzHrJD3ZPhAEG6vDF+4pgFAmVWagYACgkQAEG6vDF+ 4pjtzg//blfExUD8Eu78LtL0CL58qzUrA1bOwT52xbGl202hoykgB49x0YJ4uZMP edkwPeUzT1sizvd2/kI+q7qjCrBqwwmaFGD1QUzMX0O7d9bpNZ2r8xzrTEDTUvOh yLi4F6D1m50lY2ZFq/8iu/eTtrAHKX0zzmnz0NgNLqITbOMpp1GAvUkhFJjmL4c+ 8MPZL3hHOfVV4m06YQHmpHEbdZiJ5iqY38nXW4Lyl9xQOO9E7/OU48bt5+fFC1SN E3PRGrqFKz4O2iCOCEb/mIa94fOjaO4ymgc1/jtUUSZ3ok4+yQlz2ZK2JNPQbwhs C8MB/arxIWBdNKejXjUquPiZ4z3FbFIG9A3MptxFQQH6QudygldxifVcqh6AUeJa 44iaz0Il7oFZF1E1iiMqKHdQEoKXLo0IiGJlBkwTrUKqEQQ0V12hLcujVxKcHMxh /UTE5R/yzo5It9NiS9RSHzavTXSbe6B66zepSJv0sm3YWwgaaJZ1uShKHhs9L99L rPfTXHcAk5QTCWn66KLnNAW7NzdZ/2paZ+G7gNadqRcVyYdk9Vce3C4HXmse7eOk 6nfOaRrOSCKFbH5q05k7JUcV6On+2fUFHFpQOnxxatglrpf08WHVLsir5s8DyiZ3 WC81z23HkoqnNZ63ofw5FUdervQSmB3iK+m+R7Hqrowqg9lcT1U= =mgRO -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEiK/NIGsWEZVxh/FrYKtH/8kJUicFAmVwotEACgkQYKtH/8kJ Uif3QA/+MGZdnJywBQKQ89cFl1LMBYhm6+NC/qr6zzTJX8hwAuO31yR4WzUb6H2M Y+kZKXmWUYz98ylSBDLXWAWjfI1bHr68h+4LHPWway9SPfrt9ZtTdI0m3kTtcuTQ mIa8mkewa2MnD6lxjmkl5jUHjywpFsSCJGHnCRYmoCkUtGVDbXqp4ByBhpQPIBGu FeTj8w4EQ3MIf7zIMqm6UmpRrB+zUjwPeinHBcsv6DJvTSn2dWyqpJ1DhoA6Ulkk xBrULU2pE6b1qP6WwG81+Nsrdg9NIaO29PNBylEyQQEYQGPTvRwcfVouhRKmeAUk 2C1JOujbLk67CRfvD5CCyxvptJPW++3scrFFFY1R56B8Z+xz2Kx/IlkXv7U4W5xy AWU7kYzWY4andQdzoM1S8M+qwgWKcQ9QiddHOHgnqLLvgn8HOAYUF2LdJneHdr+t MZpKKAfYyBlz0tXT7p6YoHDVIRe5pQgb5Pd+irFCpk/40b+xoV4OD4u+zO7JW2e8 DUGvIbNwQsT8lpgQLmYJfoLZJzEVpHXUiQ9h5g8gzVnL4cDKsvxlvWc6RFTZxDaD FgHHQhY0qPyEzVNrw/88QnaT/3XwgB2Boyx1BbYmNovfHRX2zw/UsEQlVNwCjzZ9 mSUNXTCjfA1sYeX5Akah2upswstNEfs8xWMTLLywsxtJ6SB1zPI= =4Rj2 -----END PGP SIGNATURE----- Merge tag 'ffa-fixes-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes Arm FF-A fixes for v6.7 A bunch of fixes addressing issues around the notification support that was added this cycle. They address issue in partition IDs handling in ffa_notification_info_get(), notifications cleanup path and the size of the allocation in ffa_partitions_cleanup(). It also adds check for the notification enabled state so that the drivers registering the callbacks can be rejected if not enabled/supported. It also moves the partitions setup operation after the notification initialisation so that the driver has the correct state for notification enabled/supported before the partitions are initialised/setup. It also now allows FF-A initialisation to complete successfully even when the notification initialisation fails as it is an optional support in the specification. Initial support just allowed it only if the firmware didn't support notifications. Finally, it also adds a fix for smatch warning by declaring ffa_bus_type structure in the header. * tag 'ffa-fixes-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: firmware: arm_ffa: Fix ffa_notification_info_get() IDs handling firmware: arm_ffa: Fix the size of the allocation in ffa_partitions_cleanup() firmware: arm_ffa: Fix FFA notifications cleanup path firmware: arm_ffa: Add checks for the notification enabled state firmware: arm_ffa: Setup the partitions after the notification initialisation firmware: arm_ffa: Allow FF-A initialisation even when notification fails firmware: arm_ffa: Declare ffa_bus_type structure in the header Link: https://lore.kernel.org/r/20231116191603.929767-1-sudeep.holla@arm.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
b0b2981c49
@ -99,6 +99,7 @@ struct ffa_drv_info {
|
||||
void *tx_buffer;
|
||||
bool mem_ops_native;
|
||||
bool bitmap_created;
|
||||
bool notif_enabled;
|
||||
unsigned int sched_recv_irq;
|
||||
unsigned int cpuhp_state;
|
||||
struct ffa_pcpu_irq __percpu *irq_pcpu;
|
||||
@ -782,7 +783,7 @@ static void ffa_notification_info_get(void)
|
||||
if (ids_processed >= max_ids - 1)
|
||||
break;
|
||||
|
||||
part_id = packed_id_list[++ids_processed];
|
||||
part_id = packed_id_list[ids_processed++];
|
||||
|
||||
if (!ids_count[list]) { /* Global Notification */
|
||||
__do_sched_recv_cb(part_id, 0, false);
|
||||
@ -794,7 +795,7 @@ static void ffa_notification_info_get(void)
|
||||
if (ids_processed >= max_ids - 1)
|
||||
break;
|
||||
|
||||
vcpu_id = packed_id_list[++ids_processed];
|
||||
vcpu_id = packed_id_list[ids_processed++];
|
||||
|
||||
__do_sched_recv_cb(part_id, vcpu_id, true);
|
||||
}
|
||||
@ -889,6 +890,8 @@ static int ffa_memory_lend(struct ffa_mem_ops_args *args)
|
||||
|
||||
#define FFA_SECURE_PARTITION_ID_FLAG BIT(15)
|
||||
|
||||
#define ffa_notifications_disabled() (!drv_info->notif_enabled)
|
||||
|
||||
enum notify_type {
|
||||
NON_SECURE_VM,
|
||||
SECURE_PARTITION,
|
||||
@ -908,6 +911,9 @@ static int ffa_sched_recv_cb_update(u16 part_id, ffa_sched_recv_cb callback,
|
||||
struct ffa_dev_part_info *partition;
|
||||
bool cb_valid;
|
||||
|
||||
if (ffa_notifications_disabled())
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
partition = xa_load(&drv_info->partition_info, part_id);
|
||||
write_lock(&partition->rw_lock);
|
||||
|
||||
@ -1001,6 +1007,9 @@ static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
|
||||
int rc;
|
||||
enum notify_type type = ffa_notify_type_get(dev->vm_id);
|
||||
|
||||
if (ffa_notifications_disabled())
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (notify_id >= FFA_MAX_NOTIFICATIONS)
|
||||
return -EINVAL;
|
||||
|
||||
@ -1027,6 +1036,9 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
|
||||
u32 flags = 0;
|
||||
enum notify_type type = ffa_notify_type_get(dev->vm_id);
|
||||
|
||||
if (ffa_notifications_disabled())
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (notify_id >= FFA_MAX_NOTIFICATIONS)
|
||||
return -EINVAL;
|
||||
|
||||
@ -1057,6 +1069,9 @@ static int ffa_notify_send(struct ffa_device *dev, int notify_id,
|
||||
{
|
||||
u32 flags = 0;
|
||||
|
||||
if (ffa_notifications_disabled())
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (is_per_vcpu)
|
||||
flags |= (PER_VCPU_NOTIFICATION_FLAG | vcpu << 16);
|
||||
|
||||
@ -1233,7 +1248,7 @@ static void ffa_partitions_cleanup(void)
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
info = kcalloc(count, sizeof(**info), GFP_KERNEL);
|
||||
info = kcalloc(count, sizeof(*info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
@ -1311,8 +1326,10 @@ static int ffa_sched_recv_irq_map(void)
|
||||
|
||||
static void ffa_sched_recv_irq_unmap(void)
|
||||
{
|
||||
if (drv_info->sched_recv_irq)
|
||||
if (drv_info->sched_recv_irq) {
|
||||
irq_dispose_mapping(drv_info->sched_recv_irq);
|
||||
drv_info->sched_recv_irq = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int ffa_cpuhp_pcpu_irq_enable(unsigned int cpu)
|
||||
@ -1329,17 +1346,23 @@ static int ffa_cpuhp_pcpu_irq_disable(unsigned int cpu)
|
||||
|
||||
static void ffa_uninit_pcpu_irq(void)
|
||||
{
|
||||
if (drv_info->cpuhp_state)
|
||||
if (drv_info->cpuhp_state) {
|
||||
cpuhp_remove_state(drv_info->cpuhp_state);
|
||||
drv_info->cpuhp_state = 0;
|
||||
}
|
||||
|
||||
if (drv_info->notif_pcpu_wq)
|
||||
if (drv_info->notif_pcpu_wq) {
|
||||
destroy_workqueue(drv_info->notif_pcpu_wq);
|
||||
drv_info->notif_pcpu_wq = NULL;
|
||||
}
|
||||
|
||||
if (drv_info->sched_recv_irq)
|
||||
free_percpu_irq(drv_info->sched_recv_irq, drv_info->irq_pcpu);
|
||||
|
||||
if (drv_info->irq_pcpu)
|
||||
if (drv_info->irq_pcpu) {
|
||||
free_percpu(drv_info->irq_pcpu);
|
||||
drv_info->irq_pcpu = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int ffa_init_pcpu_irq(unsigned int irq)
|
||||
@ -1388,22 +1411,23 @@ static void ffa_notifications_cleanup(void)
|
||||
ffa_notification_bitmap_destroy();
|
||||
drv_info->bitmap_created = false;
|
||||
}
|
||||
drv_info->notif_enabled = false;
|
||||
}
|
||||
|
||||
static int ffa_notifications_setup(void)
|
||||
static void ffa_notifications_setup(void)
|
||||
{
|
||||
int ret, irq;
|
||||
|
||||
ret = ffa_features(FFA_NOTIFICATION_BITMAP_CREATE, 0, NULL, NULL);
|
||||
if (ret) {
|
||||
pr_err("Notifications not supported, continuing with it ..\n");
|
||||
return 0;
|
||||
pr_info("Notifications not supported, continuing with it ..\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = ffa_notification_bitmap_create();
|
||||
if (ret) {
|
||||
pr_err("notification_bitmap_create error %d\n", ret);
|
||||
return ret;
|
||||
pr_info("Notification bitmap create error %d\n", ret);
|
||||
return;
|
||||
}
|
||||
drv_info->bitmap_created = true;
|
||||
|
||||
@ -1422,14 +1446,11 @@ static int ffa_notifications_setup(void)
|
||||
hash_init(drv_info->notifier_hash);
|
||||
mutex_init(&drv_info->notify_lock);
|
||||
|
||||
/* Register internal scheduling callback */
|
||||
ret = ffa_sched_recv_cb_update(drv_info->vm_id, ffa_self_notif_handle,
|
||||
drv_info, true);
|
||||
if (!ret)
|
||||
return ret;
|
||||
drv_info->notif_enabled = true;
|
||||
return;
|
||||
cleanup:
|
||||
pr_info("Notification setup failed %d, not enabled\n", ret);
|
||||
ffa_notifications_cleanup();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init ffa_init(void)
|
||||
@ -1483,17 +1504,18 @@ static int __init ffa_init(void)
|
||||
mutex_init(&drv_info->rx_lock);
|
||||
mutex_init(&drv_info->tx_lock);
|
||||
|
||||
ffa_setup_partitions();
|
||||
|
||||
ffa_set_up_mem_ops_native_flag();
|
||||
|
||||
ret = ffa_notifications_setup();
|
||||
ffa_notifications_setup();
|
||||
|
||||
ffa_setup_partitions();
|
||||
|
||||
ret = ffa_sched_recv_cb_update(drv_info->vm_id, ffa_self_notif_handle,
|
||||
drv_info, true);
|
||||
if (ret)
|
||||
goto partitions_cleanup;
|
||||
pr_info("Failed to register driver sched callback %d\n", ret);
|
||||
|
||||
return 0;
|
||||
partitions_cleanup:
|
||||
ffa_partitions_cleanup();
|
||||
free_pages:
|
||||
if (drv_info->tx_buffer)
|
||||
free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE);
|
||||
|
@ -209,6 +209,8 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev) { return false; }
|
||||
#define module_ffa_driver(__ffa_driver) \
|
||||
module_driver(__ffa_driver, ffa_register, ffa_unregister)
|
||||
|
||||
extern struct bus_type ffa_bus_type;
|
||||
|
||||
/* FFA transport related */
|
||||
struct ffa_partition_info {
|
||||
u16 id;
|
||||
|
Loading…
x
Reference in New Issue
Block a user