Skip to content

Commit 632dca3

Browse files
lyakhlgirdwood
authored andcommitted
audio: don't override the "const" attribute
Using a type-cast to override a "const" attribute and modify read- only data is unsafe. Add a writable pointer to struct comp_driver_info instead and use it when creating component drivers dynamically. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent f623948 commit 632dca3

File tree

3 files changed

+51
-7
lines changed

3 files changed

+51
-7
lines changed

src/audio/component.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <rtos/alloc.h>
1414
#include <rtos/cache.h>
1515
#include <sof/lib/memory.h> /* for SHARED_DATA */
16+
#include <sof/lib/uuid.h>
1617
#include <sof/list.h>
1718
#include <rtos/sof.h>
1819
#include <rtos/string.h>
@@ -63,6 +64,36 @@ void comp_unregister(struct comp_driver_info *drv)
6364
k_spin_unlock(&drivers->lock, key);
6465
}
6566

67+
int comp_set_adapter_ops(const struct comp_driver *drv, const struct module_interface *ops)
68+
{
69+
struct comp_driver_list *drivers = comp_drivers_get();
70+
struct list_item *clist;
71+
72+
/* The list is only modified in IPC context, and we're in IPC context too */
73+
list_for_item(clist, &drivers->list) {
74+
struct comp_driver_info *info = container_of(clist, struct comp_driver_info, list);
75+
76+
if (!memcmp(info->drv->uid, drv->uid, UUID_SIZE)) {
77+
/*
78+
* This function should only be called for dynamically
79+
* loaded component drivers and their driver info cannot
80+
* be NULL. Do a sanity check.
81+
*/
82+
if (!info->adapter_ops) {
83+
tr_err(&comp_tr, "NULL adapter ops ptr for %pU!",
84+
info->drv->tctx->uuid_p);
85+
return -EINVAL;
86+
}
87+
88+
tr_dbg(&comp_tr, "update uuid %pU", info->drv->tctx->uuid_p);
89+
*info->adapter_ops = ops;
90+
return 0;
91+
}
92+
}
93+
94+
return -ENODEV;
95+
}
96+
6697
/* NOTE: Keep the component state diagram up to date:
6798
* sof-docs/developer_guides/firmware/components/images/comp-dev-states.pu
6899
*/

src/include/sof/audio/component.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,9 @@ struct comp_driver {
594594

595595
/** \brief Holds constant pointer to component driver */
596596
struct comp_driver_info {
597-
const struct comp_driver *drv; /**< pointer to component driver */
598-
struct list_item list; /**< list of component drivers */
597+
const struct comp_driver *drv; /**< pointer to component driver */
598+
const struct module_interface **adapter_ops; /**< pointer for updating ops */
599+
struct list_item list; /**< list of component drivers */
599600
};
600601

601602
#define COMP_PROCESSING_DOMAIN_LL 0
@@ -968,6 +969,15 @@ int comp_register(struct comp_driver_info *drv);
968969
*/
969970
void comp_unregister(struct comp_driver_info *drv);
970971

972+
/**
973+
* Set adapter ops for a dynamically created driver.
974+
*
975+
* @param drv Component driver to update.
976+
* @param ops Module interface operations.
977+
* @return 0 or a negative error code
978+
*/
979+
int comp_set_adapter_ops(const struct comp_driver *drv, const struct module_interface *ops);
980+
971981
/** @}*/
972982

973983
/**

src/library_manager/lib_manager.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -518,17 +518,19 @@ static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv,
518518
/* Intel modules expects DW size here */
519519
mod_cfg.size = args->size >> 2;
520520

521-
((struct comp_driver *)drv)->adapter_ops = native_system_agent_start(module_entry_point,
522-
module_id, instance_id,
523-
0, log_handle,
524-
&mod_cfg);
521+
const struct module_interface *ops = native_system_agent_start(module_entry_point,
522+
module_id, instance_id,
523+
0, log_handle, &mod_cfg);
525524

526-
if (!drv->adapter_ops) {
525+
if (!ops) {
527526
lib_manager_free_module(module_id);
528527
tr_err(&lib_manager_tr, "native_system_agent_start failed!");
529528
return NULL;
530529
}
531530

531+
if (comp_set_adapter_ops(drv, ops) < 0)
532+
return NULL;
533+
532534
dev = module_adapter_new(drv, config, spec);
533535
if (!dev)
534536
lib_manager_free_module(module_id);
@@ -662,6 +664,7 @@ int lib_manager_register_module(const uint32_t component_id)
662664

663665
/* Fill the new_drv_info structure with already known parameters */
664666
new_drv_info->drv = drv;
667+
new_drv_info->adapter_ops = &drv->adapter_ops;
665668

666669
/* Register new driver in the list */
667670
ret = comp_register(new_drv_info);

0 commit comments

Comments
 (0)