support for PSPLIM hardware overflow check register#128
Conversation
There was a problem hiding this comment.
Pull request overview
This PR aims to add ARMv8‑M Mainline PSPLIM-based stack overflow detection by computing a per-task stack limit during task initialization and applying it during exception return/context switching.
Changes:
- Computes and stores a per-task
stack_limitin the task context during task local-info initialization. - Extends the internal
task_tstructure to carry the computedstack_limit. - Attempts to use PSPLIM (
psplim_ns) in the Cortex‑M handler path to support hardware stack overflow detection.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| kernel/src/managers/task/task_init.c | Computes and stores stack_limit during task initialization (currently includes an inverted check that will panic). |
| kernel/src/managers/task/task_core.h | Adds stack_limit to task_t and adds ACSL annotations on task-table accessors. |
| kernel/src/managers/task/task_core.c | Adds an accessor returning the stored stack limit (name/spec currently inconsistent). |
| kernel/src/arch/asm-cortex-m/handler.c | Adds an ARMv8‑M PSPLIM block in the handler path (currently calls a missing symbol and uses the wrong instruction direction). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
9c96848 to
bb3e7d2
Compare
| if (unlikely(stack_top < meta->stack_size)) { | ||
| pr_err("security invalid stack size, not mappable "); | ||
| panic(PANIC_CONFIGURATION_MISMATCH); | ||
| } | ||
| task_ctx->stack_limit = stack_top - meta->stack_size; |
| kstatus_t status = K_ERROR_INVPARAM; | ||
| task_t *tsk = task_get_from_handle(h); | ||
| if (unlikely(tsk == NULL)) { | ||
| pr_err("invalid task handle!"); | ||
| goto err; | ||
| } | ||
| if (unlikely(stack_limit == NULL)) { | ||
| pr_err("invalid stack limit pointer!"); | ||
| goto err; | ||
| } | ||
| *stack_limit = tsk->stack_limit; | ||
| status = K_STATUS_OKAY; |
| #if CONFIG_ARCH_ARM_ARMV8MML | ||
| /* ARMv8-M Mainline support PSPLIM register to detect stack overflow */ | ||
| size_t stack_limit = 0; | ||
| if (likely(mgr_task_get_stack_size(next, &stack_limit) == K_STATUS_OKAY)) { | ||
| asm volatile ("MSR psplim, %0" : : "r" (stack_limit) ); |
| complete behaviors; | ||
| disjoint behaviors; | ||
| */ | ||
| kstatus_t mgr_task_get_stack_size(const taskh_t h, size_t* stack_limit) |
| /* clearing the sysreturn. next job is no more syscall-preempted */ | ||
| mgr_task_clear_sysreturn(next); | ||
| } | ||
| #if CONFIG_ARCH_ARM_ARMV8MML |
There was a problem hiding this comment.
This is avaiable for armv8.1m too
To be checked for armv8m-baseline (i.e. cortex m23).
May be use a dedicated config entry (e.g. HAS_STACK_LIMIT_REG which is set to y in the corresponding arch or family config entry)
| complete behaviors; | ||
| disjoint behaviors; | ||
| */ | ||
| kstatus_t mgr_task_get_stack_size(const taskh_t h, size_t* stack_limit) |
There was a problem hiding this comment.
function mgr_task_get_stack_size returns stack_limit and not stack size, should be renamed
| task_ctx->sp = mgr_task_initialize_sp(0UL, stack_top, (meta->s_text + meta->entrypoint_offset), meta->s_got); | ||
| #endif | ||
|
|
||
| if (unlikely(stack_top < meta->stack_size)) { |
There was a problem hiding this comment.
very (very) unlikely for task, lower memory should always be reserved for kernel.
This could be enforced at build time in babrican too (at memory layout forge time and device tree sanity checks, this may require a dedicated issue, i.e. check for region overlap and out of bound)
Adding, for all userspace tasks, overflow check detection using PSPLIM hardware register on ARMv8M Mainline architecture
Fixes #117