Skip to content

Commit abfee9d

Browse files
author
Jyri Sarha
committed
schedule: dp: restore the component driver on the error path
scheduler_dp_task_init() keeps its own copy of the component driver inside task_memory and repoints mod->dev->drv at it: task_memory->drv = *mod->dev->drv; mod->dev->drv = &task_memory->drv; Every error path ends at e_tmem, which releases task_memory, so mod->dev->drv is left pointing into memory that has just been freed. Nothing notices until the host tears the pipeline down and the module is freed for real: module_free(): ops = mod->dev->drv->adapter_ops That dereference faults. The module heap is a vregion whose pages are unmapped when it is released, so the access is rejected by the MMU rather than quietly returning junk: ** FATAL EXCEPTION ** CPU 2 EXCCAUSE 28 (load prohibited) ** PC 0xa008297f Backtrace: module_free <- module_adapter_free <- lib_manager_module_free <- ipc4_delete_pipeline Remember the original pointer and put it back before task_memory is freed. Verified on PTL by reverting the vpage reservation fix to bring back the partition overlap that makes DP task creation fail: 18 consecutive failures were reported to the host as errors with no heap corruption, no exception and no panic, where previously the first one halted the core. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
1 parent 6f92aee commit abfee9d

1 file changed

Lines changed: 4 additions & 0 deletions

File tree

src/schedule/zephyr_dp_schedule_application.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,8 @@ int scheduler_dp_task_init(struct task **task, const struct sof_uuid_entry *uid,
478478

479479
memset(task_memory, 0, sizeof(*task_memory));
480480

481+
const struct comp_driver *drv = mod->dev->drv;
482+
481483
task_memory->drv = *mod->dev->drv;
482484
mod->dev->drv = &task_memory->drv;
483485

@@ -643,6 +645,8 @@ int scheduler_dp_task_init(struct task **task, const struct sof_uuid_entry *uid,
643645
e_stack:
644646
user_stack_free(p_stack);
645647
e_tmem:
648+
/* the copy lives in task_memory, so stop pointing at it before freeing */
649+
mod->dev->drv = drv;
646650
mod_free(mod, task_memory);
647651
return ret;
648652
}

0 commit comments

Comments
 (0)