Repository navigation
zephyr: ll_user: carve out separate heap for LL data that kernel needs to access - #11450
Merged
Merged
Conversation
The LL user heap is a k_heap whose sys_heap metadata is in memory that the LL and IPC user threads can write, while kernel code allocates and frees from it. A user thread can therefore forge the metadata that the kernel allocator follows. As a first step towards keeping the kernel out of that heap, reserve two page-aligned areas at the start of the LL memory region: one mapped read-write and one mapped read-only into the LL memory domain. Kernel code will allocate the objects that LL user threads must access from these areas, with allocator state kept in kernel memory. The sizes are set with CONFIG_SOF_ZEPHYR_LL_KAREA_RW_SIZE and CONFIG_SOF_ZEPHYR_LL_KAREA_RO_SIZE. They are taken from the region size CONFIG_SOF_ZEPHYR_SYS_USER_HEAP_SIZE, so the kernel heap, from which the region is allocated, is not affected. The LL user heap gets the rest. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Add zephyr_ll_karea_alloc() for kernel code that creates objects in the LL memory region. It is a bump allocator whose state is in kernel-only memory, so nothing that user threads write can affect it. Allocations are cache line aligned and sized, and return the cached alias unless SOF_MEM_FLAG_COHERENT is given, like sof_heap_alloc(). Memory is never freed, which suits the objects created at boot and at secondary core bring-up that live until the firmware is reset. Add zephyr_ll_karea_contains() for checking that memory lies in an area. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Kernel code is to stop allocating from the LL user heap, whose metadata user threads can write. Add CONFIG_SOF_ZEPHYR_LL_HEAP_KERNEL_TRACE to log each allocation from and free to that heap made by a kernel thread, with size and caller address, for finding the remaining callers on target. Calls by user threads, including those that enter the kernel through system calls, are not logged. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Check that an LL user thread can write objects allocated from the kernel RW area, can read objects in the kernel RO area and faults when writing them, and that the area bounds checks and oversized requests behave as expected. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Describe the kernel RO and RW areas of the LL memory region, their allocator and the restriction on writing the RO area, and the option for tracing LL heap use by kernel threads. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
kv2019i
requested review from
LaurentiuM1234,
abonislawski,
dabekjakub,
dbaluta,
iuliana-prodan,
lbetlej,
lgirdwood,
lyakh,
marcinszkudlinski,
mmaka1,
pblaszko and
plbossart
as code owners
November 12, 2026 13:00
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
The Xtensa MMU permission split still needs target validation across cached and uncached aliases, including supervisor writes from LL-domain syscalls, since the added tests cover only cached-alias user access.
No open issues 🎉
What changed in this PR
Adds kernel-managed memory areas alongside the low-latency (LL) user heap to support syscall hardening. Persistent shared objects can use a separate allocator whose state remains inaccessible to user threads.
Changes:
- Splits the LL memory region into read-only and read-write kernel-managed areas plus the remaining user heap.
- Adds configurable area sizes, allocation and containment APIs, and optional tracing of kernel-thread use of the LL heap.
- Documents memory permissions and lifetime constraints, and adds standalone userspace tests.
| File | Description |
|---|---|
zephyr/test/userspace/test_ll_karea.c |
Adds tests for access permissions, containment, and allocation limits. |
zephyr/test/CMakeLists.txt |
Includes the new tests in standalone LL userspace builds. |
zephyr/lib/alloc.c |
Adds optional tracing of kernel-thread LL heap allocations and frees. |
zephyr/Kconfig |
Defines kernel-area sizes and the heap tracing option. |
src/kernel/schedule/zephyr_ll_user.c |
Partitions and maps the region; implements the locked bump allocator and containment checks. |
src/include/sof/userspace/README.md |
Documents the region layout, permissions, and persistent object lifetime. |
src/include/sof/schedule/ll_schedule_domain.h |
Declares and documents the kernel-area APIs. |
Review effort: Balanced
lgirdwood
approved these changes
Nov 12, 2026
PR 11450: test resultsRun date: 2026-11-13 09:20 UTC Tested commit: 6dfcc277ec3777367aa8b3a5511366c70dc0edfd |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
As part of work to harden the syscall interface, this PR adds infra to manage memory that needs to be accessed from code runnin in kernel space (mostly in system calls called by LL scheduler).
The kernel areas are for objects that kernel code creates and LL user threads access. Their
allocator is a bump allocator with kernel-only state and no free, so use it for objects that
live until the firmware is reset. The Xtensa MMU has one write permission for both rings, so
the RO area is also read-only to kernel code running in the LL memory domain, such as system
calls from LL threads: only kernel threads can write objects there.