Skip to content

schedule: dp: run DP scheduling recalc in the LL user thread - #11440

Open
kv2019i wants to merge 7 commits into
thesofproject:mainfrom
kv2019i:202611-dp-recalc-user
Open

kv2019i wants to merge 7 commits into
thesofproject:mainfrom
kv2019i:202611-dp-recalc-user

Conversation

@kv2019i

@kv2019i kv2019i commented Nov 11, 2026

Copy link
Copy Markdown
Collaborator

Series of patches to protect the kernel portions of DP scheduling better against user mode code running in DP modules. Specifically change how DP modules trigger new calculation of DP deadlines. New scheduler_dp_kick() system call that is more secure and easier to verify.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved critical flaws allow DP user code to trigger arbitrary supervisor-mode memory reads and modify other tasks’ scheduling without authorization.

4 open issues
What changed in this PR

This PR moves DP readiness and deadline calculation into the LL user thread when both schedulers use userspace, while keeping kernel-object operations behind the new scheduler_dp_kick() syscall.

Changes:

  • Separates DP scheduling calculations from kernel-side deadline updates and task wakeups.
  • Uses kernel-owned records for DP IPC handling and task counts, and bounds sink iteration.
  • Adds syscall security tests and updates scheduling documentation.
File Description
zephyr/​test/​userspace/​test_syscall_caller.c Tests caller restrictions through the new syscall.
zephyr/​test/​userspace/​test_dp_kick.c Adds kick validation, core isolation, and deadline tests.
zephyr/​test/​CMakeLists.txt Enables DP kick tests for supported configurations.
src/​schedule/​zephyr_ll.c Calls the new DP post-tick entry point.
src/​schedule/​zephyr_dp_schedule.h Declares kernel-record task counting.
src/​schedule/​zephyr_dp_schedule.c Runs userspace post-tick calculations and updates task reporting.
src/​schedule/​zephyr_dp_schedule_application.c Implements validated kicks and kernel-record IPC access.
src/​schedule/​README.md Documents userspace DP scheduling.
src/​include/​sof/​userspace/​README.md Updates syscall and boundary documentation.
src/​include/​sof/​schedule/​dp_schedule.h Defines kick structures, flags, APIs, and test hooks.
src/​audio/​module_adapter/​module/​generic.c Bounds sink iteration and skips null sinks during deadline calculation.

Review effort: Balanced

@intel-sofci

intel-sofci commented Nov 11, 2026 •

Copy link
Copy Markdown

PR 11440: test results

Run date: 2026-11-11 12:00 UTC

Tested commit: 4c5d398901974de7271f753f228d9303ee2c5ee1

mtl pass rate lnl pass rate ptl pass rate wcl pass rate nvl pass rate

When called in kernel mode, for example for MOD_INIT_INSTANCE,
scheduler_dp_thread_ipc() took the DP task event, the IPC parameter
area and the core from the module and its task memory, which DP and
other user threads can write. A forged core indexed dp_sync[] out of
bounds, and forged event and parameter pointers made the kernel post
to or write through pointers of the attacker's choice. The
LARGE_CONFIG_GET reply was also copied from a pointer the DP thread
set.

Record the core, the IPC parameter area and the reply buffer in the
kernel-only DP task record, and use the record in kernel mode. Calls
from user threads keep using the task memory, as they cannot read the
record and have no more rights than the data they can write.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
scheduler_dp_recalculate() walks the DP task list and task memory,
which the DP threads can write, and posted to the event and set the
deadline of the thread pointers stored there.

Add a scheduler_dp_kick() system call that takes the per-task results
of the calculation, finds each task in the kernel-only DP task records,
and only acts on the event and thread objects recorded there. Entries
for unknown tasks or tasks of other cores are skipped. Deadlines are
passed relative to the time of the call. Only the LL user thread may
call it.

Use it in scheduler_dp_recalculate(), which no longer calls kernel
object APIs with pointers from task memory.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
With CONFIG_SOF_USERSPACE_APPLICATION and CONFIG_SOF_USERSPACE_LL, the
scheduler_dp_ll_tick() system call ran scheduler_dp_recalculate() in
supervisor mode on every LL tick. It walks the DP task list, whose
links are in DP task memory, writes task and module state, and through
module_get_deadline() calls the sink and source ops of the module,
all of which the DP threads can write. A DP thread could use this to
make the kernel write to or call any address.

Add scheduler_dp_ll_post_tick(), called by the LL scheduler instead of
scheduler_dp_ll_tick(). In this configuration it runs the calculation
in the LL user thread, which can access DP task memory anyway, and
passes only the results to the kernel with scheduler_dp_kick(). The
scheduler_dp_ll_tick() system call is not built in this configuration.
Other configurations are unchanged.

Calculation inputs that a DP thread can still forge now only affect the
LL user thread; isolating the LL thread from DP threads is a separate
issue.

Update the system call caller test to use scheduler_dp_kick() as the
LL-only system call in this configuration.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Check that the LL user thread can signal and set the deadline of a DP
task of its own core, that entries for tasks of other cores and for
unknown tasks are skipped, and that unregistered callers, too many
entries and kernel addresses are rejected. Add test hooks for creating
DP task records without a DP task in standalone boot test builds.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
The base firmware scheduler info request is handled in kernel mode. For
the DP scheduler it walked the DP task list, whose links are in DP task
memory, and wrote one task entry per list item into the reply. A DP
thread could make the kernel read through forged links, or loop the
list so that the kernel writes past the reply buffer.

With CONFIG_SOF_USERSPACE_APPLICATION, count the tasks of the core from
the kernel-only DP task records instead. A task is counted when its
state is active, which is when it is on the DP task list. The state is
read from task memory, but only as a value, so a DP thread forging it
can only change whether its own task is counted.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
module_get_deadline() runs for DP modules, whose struct
processing_module the DP thread can write. Read the sink count once,
limit it to the size of the sink array and skip unset sinks, so a
forged count cannot make the caller read past the array.

The sink operations it calls are still taken from DP-writable memory.
With CONFIG_SOF_USERSPACE_LL this now happens in the LL user thread;
isolating it from DP threads is a separate issue.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Add scheduler_dp_kick to the syscall map and the LL-only callers, and
describe where the DP scheduling calculation runs with user-space DP
and LL.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
@kv2019i
kv2019i force-pushed the 202611-dp-recalc-user branch from 55a9ddb to 4c5d398 Compare November 11, 2026 11:33
@kv2019i

kv2019i commented Nov 11, 2026

Copy link
Copy Markdown
Collaborator Author

V2 pushed:

  • address comments so far

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The privilege-boundary and EDF scheduling changes require target-side SMP/userspace validation of isolation, spinlock interactions, and deadline behavior that the checkout cannot support.

No open issues 🎉

4 resolved since last review

Review effort: Balanced

@kv2019i kv2019i changed the title schedule: dp: run DP scheduling in the LL user thread schedule: dp: run DP scheduling recalc in the LL user thread Nov 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants