Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 35 additions & 12 deletions src/audio/module_adapter/module/dolby/dax.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ SOF_DEFINE_REG_UUID(dolby_dax_audio_processing);
#define DAX_CP_MASK 0x8
#define DAX_VOLUME_MASK 0x10
#define DAX_CTC_MASK 0x20
#define DAX_TUNING_FILE_MASK 0x40
#define DAX_PROCESSING_MASK 0x10000
#define DAX_RESET_MASK 0x20000
#define DAX_FREE_MASK 0x40000
Expand Down Expand Up @@ -241,24 +242,26 @@ static bool is_enabled(struct processing_module *mod)
return dax_ctx->enable && dax_ctx->p_dax;
}

static int set_tuning_file(struct processing_module *mod, void *value, uint32_t size)
static int set_tuning_file(struct processing_module *mod)
{
int ret = 0;
int ret = -EINVAL;
struct comp_dev *dev = mod->dev;
struct dax_adapter_data *adapter_data = module_get_private_data(mod);
struct sof_dax *dax_ctx = &adapter_data->dax_ctx;
k_spinlock_key_t key;

if (dax_buffer_alloc(mod, &dax_ctx->tuning_file_buffer, size) != 0) {
comp_err(dev, "allocate %u bytes failed for tuning file", size);
ret = -ENOMEM;
} else {
memcpy_s(dax_ctx->tuning_file_buffer.addr,
dax_ctx->tuning_file_buffer.free,
value,
size);
key = k_spin_lock(&adapter_data->lock);
if (adapter_data->tmp_tuning_buf.addr && adapter_data->tmp_tuning_buf.size > 0) {
dax_buffer_release(mod, &dax_ctx->tuning_file_buffer);
// Move the tmp_tuning_buf rather than copying
dax_ctx->tuning_file_buffer = adapter_data->tmp_tuning_buf;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure how this fixes the race... dax_buffer_release() in line 253 itself is racy - it frees directly the dax_buff->addr pointer and only then assigns NULL to it, so there's a use-after-free potential there. Also here line 254 isn't atomic - it's still the same old memcpy(), so, not very clear to me how this commit fixes any racing issues?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uha, my bad, I miss some changes. A spinlock is added to protect access to set_tuning_file.

set_tuning_file now works in process thread which has lower thread priority than set configuration, hence I dont add a spinlock in dax_set_param_wrapper.

for dax_buffer_release(), use-after-free will not happen because tuning buffer is only used in process thread through dax_find_params interface. They are always in the same thread.

adapter_data->tmp_tuning_buf.addr = NULL;
adapter_data->tmp_tuning_buf.size = 0;
ret = 0;
}
k_spin_unlock(&adapter_data->lock, key);

comp_info(dev, "allocated: tuning %u, ret %d", dax_ctx->tuning_file_buffer.size, ret);
comp_info(dev, "apply tuning %p, ret %d", dax_ctx->tuning_file_buffer.addr, ret);
return ret;
}

Expand Down Expand Up @@ -367,7 +370,19 @@ static int dax_set_param_wrapper(struct processing_module *mod,

switch (id) {
case DAX_PARAM_ID_TUNING_FILE:
set_tuning_file(mod, value, size);
if (dax_buffer_alloc(mod, &adapter_data->tmp_tuning_buf, size) != 0) {
comp_err(dev, "allocate %u bytes failed for tuning file", size);
ret = -ENOMEM;
} else {
memcpy_s(adapter_data->tmp_tuning_buf.addr,
adapter_data->tmp_tuning_buf.free,
value,
size);
flag_process(adapter_data, DAX_TUNING_FILE_MASK, DAX_FLAG_SET);
comp_info(dev, "allocated: tuning %p, size %u",
adapter_data->tmp_tuning_buf.addr,
adapter_data->tmp_tuning_buf.size);
}
break;
case DAX_PARAM_ID_ENABLE:
tmp_val = *((int32_t *)value);
Expand Down Expand Up @@ -488,6 +503,12 @@ static void check_and_update_settings(struct processing_module *mod)
if (!is_enabled(mod))
return;

if (flag_process(adapter_data, DAX_TUNING_FILE_MASK, DAX_FLAG_READ_AND_CLEAR)) {
set_tuning_file(mod);
flag_process(adapter_data, DAX_DEVICE_MASK, DAX_FLAG_SET);
flag_process(adapter_data, DAX_VOLUME_MASK, DAX_FLAG_SET);
}

if (flag_process(adapter_data, DAX_DEVICE_MASK, DAX_FLAG_READ_AND_CLEAR)) {
set_device(mod, dax_ctx->out_device);
set_tuning_device(mod, dax_ctx->tuning_device);
Expand Down Expand Up @@ -547,6 +568,7 @@ static int sof_dax_free(struct processing_module *mod)
dax_buffer_release(mod, &dax_ctx->tuning_file_buffer);
mod_data_blob_handler_free(mod, dax_ctx->blob_handler);
dax_ctx->blob_handler = NULL;
dax_buffer_release(mod, &adapter_data->tmp_tuning_buf);
mod_free(mod, adapter_data);
module_set_private_data(mod, NULL);
}
Expand Down Expand Up @@ -584,6 +606,7 @@ static int sof_dax_init(struct processing_module *mod)
adapter_data = module_get_private_data(mod);
adapter_data->comp_id = dev->ipc_config.id;
adapter_data->priority = DAX_USER_PRIORITY_DEFAULT;
k_spinlock_init(&adapter_data->lock);
dax_ctx = &adapter_data->dax_ctx;
dax_ctx->enable = 0;
dax_ctx->profile = 0;
Expand Down
3 changes: 3 additions & 0 deletions src/audio/module_adapter/module/dolby/dax.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Author: Jun Lai <jun.lai@dolby.com>
*/

#include <rtos/spinlock.h>
#include <sof/audio/module_adapter/module/generic.h>
#include <dax_inf.h>

Expand All @@ -24,6 +25,8 @@ struct dax_adapter_data {
atomic_t proc_flags;
uint32_t comp_id;
int32_t priority;
struct dax_buffer tmp_tuning_buf;
struct k_spinlock lock;
};

/**
Expand Down
4 changes: 3 additions & 1 deletion src/audio/module_adapter/module/dolby/dax_mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ uint32_t dax_query_period_frames(struct sof_dax *dax_ctx)

int dax_free(struct sof_dax *dax_ctx)
{
dax_ctx->p_dax = NULL;
return 0;
}

int dax_init(struct sof_dax *dax_ctx)
{
dax_ctx->p_dax = dax_ctx->persist_buffer.addr;
return 0;
}

Expand Down Expand Up @@ -81,7 +83,7 @@ int dax_set_ctc_enable(int32_t enable, struct sof_dax *dax_ctx)

const char *dax_get_version(void)
{
return "";
return "mock_version";
}

void *dax_find_params(uint32_t query_id,
Expand Down
Loading