-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
core: arm32: handle aborts in system mode #1703
Conversation
Can this patch handle the abort which occurs in native interrupt handler(IRQ/FIQ MODE)? |
With regards to IRQ/FIQ mode it's the same behavior as today, that is, either the abort is reported as an unhandled abort or there's a panic in |
I have tested this on my b2260 (ARMv7). I get the exact same backtrace with and without this change when generating an abort from the abort handler :( The initial abort backtrace is fine but the backtrace from the abort-in-abort is buggy (always shows twice the current function and the Same status with initial abort being issued either from core service or from user TA execution. This is not a very constructive comment but I did not manage to find where's the issue... |
core/arch/arm/kernel/thread_a32.S
Outdated
* r1 is initialized as a temporary stack pointer until we've | ||
* switched to system mode. | ||
*/ | ||
tst r1, #(THREAD_CLF_SAVED_SHIFT + THREAD_CLF_ABORT_SHIFT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be tst r1, #(THREAD_CLF_ABORT << THREAD_CLF_SAVED_SHIFT)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I'll fix.
core/arch/arm/kernel/thread_a32.S
Outdated
* switched to system mode. | ||
*/ | ||
tst r1, #(THREAD_CLF_SAVED_SHIFT + THREAD_CLF_ABORT_SHIFT) | ||
orrne r1, r1, #THREAD_CLF_TMP /* flags |= THREAD_CLF_TMP; */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
THREAD_CLF_TMP
seems not being used anywhere (but set here).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but this is the same for AArch64. This flag is kept to be able to tell which state we're executing in. AArch64 doesn't have as many mode bits as AArch32 in CPSR so it's mostly to compensate for that.
It's probably only useful for debug purposes, but I'd prefer to keep it reliable in either case for the time being.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
Please test again with the added fix. |
Stack info and link register value are still wrong in abort-in-abort case, because read from current exec mode context through --- a/core/arch/arm/kernel/abort.c
+++ b/core/arch/arm/kernel/abort.c
@@ -101,8 +101,13 @@ static void __print_stack_unwind_arm32(struct abort_info *ai)
state.registers[10] = ai->regs->r10;
state.registers[11] = ai->regs->r11;
- state.registers[13] = read_mode_sp(ai->regs->spsr & CPSR_MODE_MASK);
- state.registers[14] = read_mode_lr(ai->regs->spsr & CPSR_MODE_MASK);
+ if (thread_is_from_abort_mode(NULL)) {
+ state.registers[13] = ai->regs->usr_sp;
+ state.registers[14] = ai->regs->usr_lr;
+ } else {
+ state.registers[13] = read_mode_sp(ai->regs->spsr & CPSR_MODE_MASK);
+ state.registers[14] = read_mode_lr(ai->regs->spsr & CPSR_MODE_MASK);
+ }
state.registers[15] = ai->pc;
EMSG_RAW("Call stack:");
@@ -245,9 +250,11 @@ static __maybe_unused void __print_abort_info(
ai->regs->r0, ai->regs->r4, ai->regs->r8, ai->regs->ip);
EMSG_RAW(" r1 0x%08x r5 0x%08x r9 0x%08x sp 0x%08x",
ai->regs->r1, ai->regs->r5, ai->regs->r9,
+ thread_is_from_abort_mode(NULL) ? ai->regs->usr_sp :
read_mode_sp(ai->regs->spsr & CPSR_MODE_MASK));
EMSG_RAW(" r2 0x%08x r6 0x%08x r10 0x%08x lr 0x%08x",
ai->regs->r2, ai->regs->r6, ai->regs->r10,
+ thread_is_from_abort_mode(NULL) ? ai->regs->usr_lr :
read_mode_lr(ai->regs->spsr & CPSR_MODE_MASK));
EMSG_RAW(" r3 0x%08x r7 0x%08x r11 0x%08x pc 0x%08x",
ai->regs->r3, ai->regs->r7, ai->regs->r11, ai->pc); |
Thanks for the patch @etienne-lms, I ended up doing it slightly different. As far as I can see in QEMU it's OK for aborts in pager and in boot thread. |
Agree with the changes. Tested ok on b2260 on various abort conditions. Note an build error in 64bit mode reported by travis. static __maybe_unused void __print_abort_info(struct abort_info *ai,
const char *ctx __maybe_unused)
{
+#ifdef ARM32
uint32_t mode = ai->regs->spsr & CPSR_MODE_MASK;
__maybe_unused uint32_t sp;
__maybe_unused uint32_t lr;
if (mode == CPSR_MODE_USR || mode == CPSR_MODE_SYS) {
sp = ai->regs->usr_sp;
lr = ai->regs->usr_lr;
} else {
sp = read_mode_sp(mode);
lr = read_mode_lr(mode);
}
+#endif
EMSG_RAW(""); |
Updated |
core/arch/arm/kernel/abort.c
Outdated
static __maybe_unused void __print_abort_info( | ||
struct abort_info *ai __maybe_unused, | ||
const char *ctx __maybe_unused) | ||
static __maybe_unused void __print_abort_info(struct abort_info *ai, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
must preserve __maybe_unused
for case ARM64 and LOG_LEVEL==0
core/arch/arm/kernel/thread.c
Outdated
@@ -644,14 +644,9 @@ size_t thread_stack_size(void) | |||
|
|||
bool thread_is_from_abort_mode(struct thread_abort_regs __maybe_unused *regs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As argument regs
is useless now, maybe remove it within this P-R.
core/arch/arm/kernel/thread_a32.S
Outdated
* cpsr is in mode undef or abort | ||
* sp is still pointing to struct thread_core_local belonging to | ||
* this core. | ||
* {r0-r3} are saved in struct thread_core_local pointed to by sp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/{r0-r3}
/{r0,r1}
/
core/arch/arm/kernel/thread_a32.S
Outdated
* sp is still pointing to struct thread_core_local belonging to | ||
* this core. | ||
* {r0-r3} are saved in struct thread_core_local pointed to by sp | ||
* {r4-r11, ip} are untouched. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/r4-r11
/r2-r11
/
Comments addressed |
|
Switch to handle aborts in system mode in order to be able to give a stack trace in case an abort occurs in the abort handler. In a manner similar to the AArch64 implementation are abort and undef mode stack pointers pointing to the struct thread_core_local of corresponding cpu. Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org> Tested-by: Jens Wiklander <jens.wiklander@linaro.org> (QEMU) Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
119145c
to
ccf8290
Compare
Squashed, tags applied and rebased. |
Switch to handle aborts in system mode in order to be able to give a
stack trace in case an abort occurs in the abort handler.
In a manner similar to the AArch64 implementation are abort and undef
mode stack pointers pointing to the struct thread_core_local of
corresponding cpu.
Tested-by: Jens Wiklander jens.wiklander@linaro.org (Hikey)
Signed-off-by: Jens Wiklander jens.wiklander@linaro.org