Skip to content

os/arch/arm/src/armv7-m: Preserve EXC_RETURN across trampoline - #7456

Open
seokhun-eom24 wants to merge 1 commit into
Samsung:masterfrom
seokhun-eom24:260727-fix-armv7m-sigaction
Open

os/arch/arm/src/armv7-m: Preserve EXC_RETURN across trampoline#7456
seokhun-eom24 wants to merge 1 commit into
Samsung:masterfrom
seokhun-eom24:260727-fix-armv7m-sigaction

Conversation

@seokhun-eom24

@seokhun-eom24 seokhun-eom24 commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

The common-vector register contains REG_EXC_RETURN in both flat and protected builds.
Signal delivery temporarily redirects the saved context to up_sigdeliver, so it must save the original EXC_RETURN, force the trampoline to return through privileged Thread mode, and restore the original value after the handler completes.
Move the EXC_RETURN save, update, and restore outside the protected-build guard while keeping LR handling protected-only.
Always select EXC_RETURN_PRIVTHR for a non-running target instead of only converting handler-mode contexts.
This prevents a blocked task from entering the kernel signal trampoline with an incompatible handler or unprivileged return state and avoids exception-return integrity faults.

In CONFIG_ARM_CMNVECTOR is not set and CONFIG_BUILD_PROTECTED is not set case we're setting EXC_RETURN_PRIVTHR in up_lazyexception.S

 #ifdef CONFIG_BUILD_PROTECTED
	ldmia	r0, {r2-r11,r14}		/* Recover R4-R11, r14 + 2 temp values */
 #else
	ldmia	r0, {r2-r11}			/* Recover R4-R11 + 2 temp values */
	ldr	r14, =EXC_RETURN_PRIVTHR	/* Load the special value */
 #endif

@seokhun-eom24
seokhun-eom24 force-pushed the 260727-fix-armv7m-sigaction branch from 4af6d8f to c7e320b Compare July 27, 2026 03:46
@seokhun-eom24

Copy link
Copy Markdown
Contributor Author

Similar PR: #7385

@rish-sg

rish-sg commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

LGTM

@namanjain7

Copy link
Copy Markdown
Contributor

we have verified it on mediatek_2.0 . It's working fine.
However, below additional changes needed:

  1. in irq.h , since we want to save current priority level of task. We will need to add saved_exec_ret with ARM_CMNVECTOR. Like below:
    #if defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_ARM_CMNVECTOR)
    uint32_t saved_lr;
    uint32_t saved_exec_ret;
    #endif

  2. Add ARM_CMNVECTOR in REG_EXC_RETURN in declaration.
    #if defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_ARM_CMNVECTOR)
    #define REG_EXC_RETURN (10) /* EXC_RETURN */

After these changes, all build issues will be resolved when we enable CONFIG_ARM_CMNVECTOR in Mediatek_2.0 with PR#7456

@seokhun-eom24
seokhun-eom24 force-pushed the 260727-fix-armv7m-sigaction branch from c7e320b to 7edee8a Compare July 29, 2026 10:14

@namanjain7 namanjain7 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.

LGTM

#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.saved_lr = current_regs[REG_LR];
#endif
#if defined(CONFIG_ARM_CMNVECTOR) || defined(CONFIG_BUILD_PROTECTED)

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.

Could you please explan why CONFIG_ARM_CMNVECTOR checking is added?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

REG_EXC_RETURN is only available when CONFIG_ARM_CMNVECTOR or CONFIG_BUILD_PROTECTED is enabled.
Therefore, the usage should be guarded with #if defined(CONFIG_ARM_CMNVECTOR) || defined(CONFIG_BUILD_PROTECTED) to handle the case where both options are disabled like qemu/build_test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ARM_CMNVECTOR BUILD_PROTECTED Context Layout Header REG_EXC_RETURN saved_exc_ret Reason
irq_lazyfpu.h Standard lazy-FPU / flat context does not have a dedicated slot for storing EXC_RETURN.
irq_lazyfpu.h In protected builds, EXC_RETURN must be saved in slot 10 to manage privilege return states.
irq_cmnvector.h Common-vector context always preserves EXC_RETURN, even in flat builds.
irq_cmnvector.h Applies both common-vector requirements and protected-build privilege tracking.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

#if defined(CONFIG_ARM_CMNVECTOR) || defined(CONFIG_BUILD_PROTECTED)
	/* All tasks start via a stub function in kernel space.  So all
	 * tasks must start in privileged thread mode.  If CONFIG_BUILD_PROTECTED
	 * is defined, then that stub function will switch to unprivileged
	 * mode before transferring control to the user task.
	 */

	xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;

#endif							/* CONFIG_ARM_CMNVECTOR || CONFIG_BUILD_PROTECTED */

https://github.com/Samsung/TizenRT/blob/master/os/arch/arm/src/armv7-m/up_initialstate.c#L150

This is why we need to use #if defined(CONFIG_ARM_CMNVECTOR) || defined(CONFIG_BUILD_PROTECTED)

The common-vector register contains REG_EXC_RETURN in both flat and protected builds.
Signal delivery temporarily redirects the saved context to up_sigdeliver, so it must save the original EXC_RETURN, force the trampoline to return through privileged Thread mode, and restore the original value after the handler completes.
Move the EXC_RETURN save, update, and restore outside the protected-build guard while keeping LR handling protected-only.
Always select EXC_RETURN_PRIVTHR for a non-running target instead of only converting handler-mode contexts.
This prevents a blocked task from entering the kernel signal trampoline with an incompatible handler or unprivileged return state and avoids exception-return integrity faults.

In `CONFIG_ARM_CMNVECTOR is not set` and `CONFIG_BUILD_PROTECTED is not set` case we're setting `EXC_RETURN_PRIVTHR` in up_lazyexception.S
```
 #ifdef CONFIG_BUILD_PROTECTED
	ldmia	r0, {r2-r11,r14}		/* Recover R4-R11, r14 + 2 temp values */
 #else
	ldmia	r0, {r2-r11}			/* Recover R4-R11 + 2 temp values */
	ldr	r14, =EXC_RETURN_PRIVTHR	/* Load the special value */
 #endif
```

Signed-off-by: seokhun-eom <seokhun.eom@samsung.com>
@seokhun-eom24
seokhun-eom24 force-pushed the 260727-fix-armv7m-sigaction branch from 7edee8a to d276a0e Compare August 31, 2026 06:43
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.

4 participants