[userspace LL] vregion related syscalls - #11108
Open
lyakh wants to merge 4 commits into
Open
Conversation
lyakh
requested review from
abonislawski,
dbaluta,
iuliana-prodan,
kv2019i,
lbetlej,
lgirdwood,
mmaka1,
plbossart and
ranj063
as code owners
August 20, 2026 14:40
Contributor
There was a problem hiding this comment.
Pull request overview
Adds Zephyr userspace support for SOF “vregion” allocations to enable userspace LL + DP integration (part of #10945), including syscall plumbing and module-adapter wiring to map vregion memory into the LL userspace memory domain.
Changes:
- Introduces Zephyr syscall handlers/marshalling for vregion alloc/free/get/put/set_interim.
- Refactors Zephyr vregion implementation entrypoints to
z_impl_*to back the new syscalls. - Extends module-adapter allocation flow to create/map/unmap vregions for DP modules and plumbs vregion start/size through
mod_alloc_ctx.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| zephyr/syscall/vregion.c | New syscall verification + marshalling includes for vregion APIs. |
| zephyr/lib/vregion.c | Switches vregion APIs to z_impl_* entrypoints and adjusts symbol exports accordingly. |
| zephyr/Kconfig | Adds SOF_USERSPACE_INTERFACE_VREGION and selects it from SOF_USERSPACE_LL. |
| zephyr/include/rtos/alloc.h | Extends mod_alloc_ctx with vregion start/size metadata for domain mapping. |
| zephyr/CMakeLists.txt | Adds syscall header generation and builds the new vregion syscall source. |
| src/include/sof/lib/vregion.h | Marks vregion APIs as __syscall and includes generated syscall header. |
| src/include/sof/audio/module_adapter/module/generic.h | Exposes module-adapter vregion map/unmap as syscalls for full Zephyr app. |
| src/audio/module_adapter/module_adapter.c | Implements vregion creation + mem-domain partition mapping and adds syscall verifiers. |
| src/audio/buffers/comp_buffer.c | Routes vregion-backed buffer free through the new shared vregion-free helper. |
Suppressed comments (2)
src/audio/module_adapter/module_adapter.c:134
- module_adapter_vreg_free() decrements the vregion refcount (and may free the vregion pages) before removing the user mem-domain partitions. If vregion_put() frees the pages, the user partition remains until module_adapter_vreg_unmap() runs, creating a window where freed (and potentially reallocated) pages stay user-accessible. Consider unmapping first and freeing the vregion atomically in kernel code when the refcount reaches 0.
void module_adapter_vreg_free(struct mod_alloc_ctx *alloc)
{
if (vregion_put(alloc->vreg))
return;
module_adapter_vreg_unmap(alloc);
sof_heap_free(alloc->heap, alloc);
src/audio/module_adapter/module_adapter.c:255
- The syscall verifier for module_adapter_vreg_unmap() only checks that the alloc struct is readable. In userspace-LL configurations alloc lives in user-writable memory, so a caller can forge vreg_start/vreg_size and attempt to remove arbitrary partitions from zephyr_ll_mem_domain(). Add validation that alloc refers to an expected allocation and that (vreg_start,vreg_size) match the vregion’s actual mem_info (or avoid taking alloc from user-space entirely).
void z_vrfy_module_adapter_vreg_unmap(const struct mod_alloc_ctx *alloc)
{
K_OOPS(K_SYSCALL_MEMORY_READ(alloc, sizeof(*alloc)));
z_impl_module_adapter_vreg_unmap(alloc);
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
195
to
+199
| memset(mod, 0, sizeof(*mod)); | ||
| alloc->heap = mod_heap; | ||
| alloc->vreg = mod_vreg; | ||
| alloc->vreg_start = vreg_start; | ||
| alloc->vreg_size = vreg_size; |
Comment on lines
+79
to
+98
| struct k_mem_partition part = { | ||
| .start = *vreg_start, | ||
| .size = *vreg_size, | ||
| .attr = K_MEM_PARTITION_P_RW_U_RW | XTENSA_MMU_CACHED_WB, | ||
| }; | ||
| int ret = k_mem_domain_add_partition(zephyr_ll_mem_domain(), &part); | ||
|
|
||
| if (ret < 0) { | ||
| vregion_put(vr); | ||
| return NULL; | ||
| } | ||
|
|
||
| part.start = (uintptr_t)sys_cache_uncached_ptr_get((void *)part.start); | ||
| part.attr = K_MEM_PARTITION_P_RW_U_RW; | ||
|
|
||
| ret = k_mem_domain_add_partition(zephyr_ll_mem_domain(), &part); | ||
| if (ret < 0) { | ||
| vregion_put(vr); | ||
| return NULL; | ||
| } |
Comment on lines
+9
to
+21
| static bool vregion_verify(struct vregion *vr) | ||
| { | ||
| if (!vr) | ||
| return false; | ||
|
|
||
| size_t vr_size = 0; | ||
| uintptr_t vr_start; | ||
|
|
||
| vregion_mem_info(vr, &vr_size, &vr_start); | ||
| if (vr_size) | ||
| K_OOPS(K_SYSCALL_MEMORY_WRITE((void *)vr_start, vr_size)); | ||
|
|
||
| return true; |
Comment on lines
8
to
11
| #include <stddef.h> | ||
| #include <stdint.h> | ||
| #include <zephyr/toolchain.h> | ||
|
|
Comment on lines
+197
to
+199
| __syscall struct vregion *module_adapter_vreg_new(const struct comp_ipc_config *config, | ||
| uintptr_t *vreg_start, size_t *vreg_size); | ||
| __syscall void module_adapter_vreg_unmap(const struct mod_alloc_ctx *alloc); |
Comment on lines
+630
to
+633
| zephyr_syscall_header(include/rtos/alloc.h) | ||
| zephyr_library_sources_ifdef(CONFIG_SOF_USERSPACE_INTERFACE_ALLOC syscall/alloc.c) | ||
| zephyr_syscall_header(${SOF_SRC_PATH}/include/sof/lib/vregion.h) | ||
| zephyr_library_sources(syscall/vregion.c) |
lyakh
force-pushed
the
vreg
branch
4 times, most recently
from
August 20, 2026 15:25
ca13168 to
4f46949
Compare
Add two syscall functions to allocate and map, and to unmap vregion for userspace modules. For now only used for DP modules. Add module_adapter.c to cmocka builds for the new module_adapter_vreg_free() function, which is now called in comp_buffer.c. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Make vregion_alloc(), vregion_alloc_coherent(), vregion_alloc_align(), vregion_alloc_coherent_align(), and vregion_free() available as Zephyr system calls for user-space threads. Add K_SYSCALL_MEMORY_WRITE verification to all syscall handlers to validate the calling thread has access to the vregion's managed memory area. Add CONFIG_SOF_USERSPACE_INTERFACE_VREGION Kconfig option to control the feature. It is auto-selected by SOF_USERSPACE_LL when SOF_VREGIONS is enabled. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Extract common syscall verification code into a function. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
vregion_get(), vregion_put() and vregion_set_interim() should also be callable from the userspace. Make them syscalls. Also remove redundant symbol exporting since the vregion API shouldn't be used directly by LLEXT modules. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
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.
vregion system calls, needed when integrating userspace LL and DP
part of #10945