Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AArch32 exception exit routine behaves incorrectly on fatal exceptions #31511

Closed
stephanosio opened this issue Jan 22, 2021 · 1 comment · Fixed by #31519
Closed

AArch32 exception exit routine behaves incorrectly on fatal exceptions #31511

stephanosio opened this issue Jan 22, 2021 · 1 comment · Fixed by #31519
Assignees
Labels
area: ARM ARM (32-bit) Architecture area: Exception Handling bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug
Milestone

Comments

@stephanosio
Copy link
Member

The AArch32 exception exit routine (z_arm_exc_exit) behaves incorrectly on fatal exceptions.

There are two bugs that are currently identified in the z_arm_exc_exit implementation:

1. Invalid return address when calling z_arm_pendsv

When an exception is fatal and the current thread is aborted, the z_arm_exc_exit attempts to switch to the next scheduled thread by invoking z_arm_pendsv:

/* If the fault is not fatal, return to the current thread context */
cmp r0, #0
beq __EXIT_EXC
/*
* If the fault is fatal, the current thread must have been aborted by
* the exception handler. Clean up the exception stack frame and switch
* to the next scheduled thread.
*/
/* Clean up exception stack frame */
add sp, #32
/* Switch in the next scheduled thread */
bl z_arm_pendsv

The z_arm_exc_exit function is invoked by the exception handlers in the corresponding exception mode (e.g. MODE_UND for undefined instruction exception), and the branch to z_arm_pendsv here saves the return address to the corresponding exception mode link register (e.g. lr_und for undefined instruction exception).

The z_arm_pendsv function assumes that the calling mode is the SVC mode, as is the case for the normal IRQs handled by the _isr_wrapper, and switches to the SVC mode during context switch:

/* restore r4-r11 and sp for incoming thread */
cps #MODE_SYS
ldm r0, {r4-r11, sp}
cps #MODE_SVC

When the z_arm_pendsv function returns, the current execution mode is the SVC mode, and the value of lr at this point is that of lr_svc.

2. Caller-saved register is referenced after a call

The following code incorrectly assumes that r3, a caller-saved register, contains _kernel after a call to z_arm_pendsv:

/* Switch in the next scheduled thread */
bl z_arm_pendsv
/* Decrement exception nesting count */
ldr r0, [r3, #_kernel_offset_to_nested]
sub r0, r0, #1
str r0, [r3, #_kernel_offset_to_nested]

r3 must be reloaded at this point. Note that using a callee-saved register here is not an option because z_arm_pendsv exits with the callee-saved registers of the incoming context.

@stephanosio stephanosio added bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug area: ARM ARM (32-bit) Architecture area: Exception Handling labels Jan 22, 2021
@stephanosio stephanosio added this to the v2.5.0 milestone Jan 22, 2021
@stephanosio stephanosio self-assigned this Jan 22, 2021
@stephanosio
Copy link
Member Author

I will post a PR fixing this soon.

stephanosio added a commit to stephanosio/zephyr that referenced this issue Jan 22, 2021
This commit fixes the following bugs in the AArch32 z_arm_exc_exit
routine:

1. Invalid return address when calling `z_arm_pendsv` from the
   exception-specific mode

2. Caller-saved register is referenced after a call to `z_arm_pendsv`

For more details, refer to the issue zephyrproject-rtos#31511.

Signed-off-by: Stephanos Ioannidis <[email protected]>
nashif pushed a commit that referenced this issue Jan 26, 2021
This commit fixes the following bugs in the AArch32 z_arm_exc_exit
routine:

1. Invalid return address when calling `z_arm_pendsv` from the
   exception-specific mode

2. Caller-saved register is referenced after a call to `z_arm_pendsv`

For more details, refer to the issue #31511.

Signed-off-by: Stephanos Ioannidis <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: ARM ARM (32-bit) Architecture area: Exception Handling bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant